В основном неизменный 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 вовлечены.

Другие вопросы по тегам