В основном неизменный NaturalId
У меня простой
public class SomeEntity {
@Id private Integer id;
@NaturalId private User owner;
@NaturalId(mutable=true) private String name;
...
}
и естественный идентификатор создает уникальный ключ (хорошо!), и это делает owner
неизменный из спящего Это тоже хорошо, однако, однажды в голубой луне, администратор должен сменить владельца. Поэтому я, кажется, вынужден сделать его также изменчивым, что действительно не нравится.
Я мог бы использовать простой SQL для его преодоления, но это означало бы ложь, что мне тоже не нравится, так как это могло обмануть спящий режим и сделать что-то неправильно.
Я ищу чистый способ заявить что-то вроде "неизменяемого, кроме случаев, когда я говорю" (хотя я пессимистично настроен относительно того, что это возможно). Мне также любопытно, каковы недостатки альтернатив.
1 ответ
По моему мнению: эта ситуация показывает, что владелец и имя больше не являются естественными идентификаторами. Это просто свойства, которые на уровне обслуживания могут время от времени изменяться, и существует ограничение на наличие уникальной пары owner, name
ценности с точки зрения бизнес-уровня. Таким образом, ситуация "за исключением случаев, когда я говорю" должна быть разрешена на уровне "бизнес"-сервиса: то есть владелец становится изменяемым, и внутри ваших служб вы создаете отдельный метод для его изменения, другие методы не должны изменять это свойство. то есть:
@Secured(ADMIN_ONLY_ACCESS)
public SomeEntity modifyAdministrative(SomeEntity entity) {
//here you allow to modify owner
}
public SomeEntity modify(SomeEntity entity) {
// here owner should be used as readonly property
// and you can controll this only on your own,
// hibernate is not able to support you anymore with immutability control
}
Или вы можете отобразить ваши данные некоторых таблиц сущностей во вторую другую сущность и повторно использовать NaturalId
поведения, предоставляемые Hibernate, то есть
public class SomeEntity {
// Keep this for general usage
@Id private Integer id;
@NaturalId private User owner;
@NaturalId(mutable=true) private String name;
...
}
public class SomeEntityForAdmin {
// use this for administrative usage
@Id private Integer id;
private User owner;
private String name;
...
}
SomeEntityForAdmin
используется только для административных ситуаций, когда требуется изменить owner
, И весь остальной код сохраняется как есть.
Но будьте осторожны: у вас будут сложные проблемы с кешами (вы должны создать правильные стратегии аннулирования для своих кешей, как только изменения в SomeEntityForAdmin
или же SomeEntity
и это становится полным беспорядком, когда в одной транзакции SomeEntity
а также SomeEntityForAdmin
вовлечены.