Если в Hibernate пометить сущность аннотацией @org.hibernate.annotations.Immutable, то Hibernate учтёт этот момент и осуществит ряд оптимизаций при работе с данной сущностью.
Аннотация @org.hibernate.annotations.Immutable ставится над классом предметной области:
1 2 3 4 |
@Entity @org.hibernate.annotations.Immutable public class Client { ... |
Это не стандартная JPA аннотация, поэтому пишем её полное имя. При работе с такой сущностью Hibernate не будет создавать SQL запросы на обновление (UPDATE). Не будет проводить проверки на грязное чтение и т.п.
У такого класса предметной области может не быть сеттеров. Пользователь задаёт все значения в конструкторе. А Hibernate для установки значений будет использовать прямой доступ к полям через механизм рефлексии.
Попытки обновить значение того или иного поля в БД через такую сущность с помощью Hibernate ни к чему не приведут. Давайте это увидим.
Создадим класс предметной области следующего содержания:
1 2 3 4 5 6 7 8 9 10 |
@Entity @org.hibernate.annotations.Immutable public class Person { @Id @GeneratedValue private Long id; private String name; private Integer age; //Конструкторы, геттеры и сеттеры, equals(), hashCode() и т.д. } |
Создадим для него репозиторий:
1 2 3 |
@Repository public interface PersonRepository extends JpaRepository<Person, Long> { } |
Создадим тестовый класс:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
@SpringBootTest class TestApplicationTests { @Autowired PersonRepository personRepository; @Test void contextLoads() { Person irina = new Person("Irina", 30); personRepository.save(irina); irina.setAge(31); personRepository.save(irina); List<Person> tableData = personRepository.findAll(); assertEquals(tableData.size(), 1); assertEquals(tableData.get(0).getAge(), 30); } } |
Из теста видно, что хотя мы и изменили объект irina (в нашем случае у него были сеттеры) и попытались сохранить изменения в БД, но когда мы достали эту строку из базы, наши изменения в ней не были отражены.
Также данный тест выявляет важный момент. После всех манипуляций выше в таблице в строке с id = 1 колонка age содержит значение 30, а объект irina также имеет значение поля id равное 1, но значение поля age у этого объекта равно уже 31. Данные в таблице и данные в объекте рассинхронизированы.
В общем и целом это задача программиста обеспечить немутабельность объектов. Не всегда есть возможность убрать из класса сеттеры, поэтому задача может оказаться нетривиальной.