Рубрики
Без рубрики

@Immutable в спячке

Быстрое и практичное руководство по @Immutable аннотации в Hibernate

Автор оригинала: baeldung.

1. Обзор

В этой статье мы поговорим о том, как мы можем сделать объект, сбор или атрибут Неизменяемые в Спячке.

По умолчанию поля являются мутируемыми, что означает, что мы можем выполнять операции на них, которые меняют их состояние.

2. Мавен

Чтобы получить наш проект и работает, мы сначала должны добавить необходимые зависимости в нашу пом.xml . И по мере того, как мы работаем с Hibernate, мы добавим соответствующий зависимость :


    org.hibernate
    hibernate-core
    5.2.8.Final

И потому, что мы работаем с ХСЛДБ , нам также нужно:


    org.hsqldb
    hsqldb
    2.3.4

3. Аннотация о сущностях

Во-первых, давайте определим простой класс сущности:

@Entity
@Immutable
@Table(name = "events_generated")
public class EventGeneratedId {

    @Id
    @Column(name = "event_generated_id")
    @GeneratedValue(generator = "increment")
    @GenericGenerator(name = "increment", strategy = "increment")
    private Long id;

    @Column(name = "name")
    private String name;
    @Column(name = "description")
    private String description;

    // standard setters and getters
}

Как вы заметили, мы добавили уже @Immutable аннотация к нашей сущности, так что если мы попытаемся сохранить Событие :

@Test
public void addEvent() {
    Event event = new Event();
    event.setId(2L);
    event.setTitle("Public Event");
    session.save(event);
    session.getTransaction().commit();
    session.close();
}

Тогда мы должны получить выход:

Hibernate: insert into events (title, event_id) values (?, ?)

Выход должен быть таким же, даже если мы удалим аннотацию, то есть нет никакого эффекта, когда мы пытаемся добавить сущность, независимо от аннотации.

Важно также отметить, что в нашей EventGeneratedId лица, мы добавили Сгенерированная аннотация, но это будет иметь значение только тогда, когда мы создаем сущность. Это потому, что он определяет стратегию генерации для идентификатора – любые другие операции не повлияют на Id поле из-за Неизменяемые аннотация.

3.1. Обновление сущности

Теперь у нас не было проблем с сохранением сущности, давайте попробуем обновить ее:

@Test
public void updateEvent() {
    Event event = (Event) session.createQuery(
      "FROM Event WHERE title='My Event'").list().get(0);
    event.setTitle("Public Event");
    session.saveOrUpdate(event);
    session.getTransaction().commit();
}

Hibernate будет просто игнорировать обновление операции без каких-либо исключений. Однако, если мы удалим @Immutable аннотация мы получаем другой результат:

Hibernate: select ... from events where title='My Event'
Hibernate: update events set title=? where event_id=?

Это говорит нам о том, что наш объект теперь является является значением по умолчанию, если мы не включим аннотацию) и позволит обновлению делать свою работу.

3.2. Удаление сущности

Когда дело доходит до удаления сущности:

@Test
public void deleteEvent() {
    Event event = (Event) session.createQuery(
      "FROM Event WHERE title='My Event'").list().get(0);
    session.delete(event);
    session.getTransaction().commit();
}

Мы сможем выполнить удаление независимо от того, является ли оно мутируемым или нет:

Hibernate: select ... from events where title='My Event'
Hibernate: delete from events where event_id=?

4. Аннотация о коллекциях

До сих пор мы видели, что аннотация делает для сущностей, но, как мы уже упоминали в начале, она также может быть применена к коллекциям.

Во-первых, давайте добавим коллекцию к нашему Событие класс:

@Immutable
public Set getGuestList() {
    return guestList;
}

Так же, как и раньше, мы добавили аннотацию заранее, так что если мы идем вперед и попытаться добавить элемент в нашу коллекцию:

org.hibernate.HibernateException: 
  changed an immutable collection instance: [com.baeldung.entities.Event.guestList#1]

На этот раз мы получаем исключение, потому что с коллекциями мы не можем добавить или удалить их.

4.1. Удаление коллекций

Другой сценарий, где Коллекционая будучи неизменным будет бросать исключение это всякий раз, когда мы пытаемся удалить, и мы установили @Cascade аннотация.

Таким образом, всякий раз, когда @Immutable присутствует, и мы пытаемся удалить:

@Test
public void deleteCascade() {
    Event event = (Event) session.createQuery(
      "FROM Event WHERE title='Public Event'").list().get(0);
    String guest = event.getGuestList().iterator().next();
    event.getGuestList().remove(guest);
    session.saveOrUpdate(event);
    session.getTransaction().commit();
}

выпуск:

org.hibernate.HibernateException: 
  changed an immutable collection instance:
  [com.baeldung.entities.Event.guestList#1]

5.XML Заметки

Наконец, конфигурация также может быть выполнена с помощью XML через мутируемые и ложные атрибут:


    
        
            
        
        
    

Однако, поскольку мы в основном реализовали примеры с использованием метода аннотации, мы не будем в подробности с помощью XML.

6. Заключение

В этой быстрой статье мы исследуем полезные @Immutable аннотация из Hibernate, и как это может помочь нам определить лучшую семантику и ограничения на наши данные.

Как всегда, реализация всех этих примеров и фрагментов можно найти в проект GitHub . Это Maven основе проекта, поэтому она должна быть легко импортировать и запускать.