In mine oppinion: this situations shows that owner and name are not natural ids anymore. They are simply the properties, which from the service level could be changed from time to time, and there is a limit on having unique pair of owner, name
values from business level perspective. So the "immutable except when I say" situation should be resolved on "business"-service level: i.e. owner becomes mutable, and inside of your services you are creating separate method to modify it, other methods should not modify this property. i.e.:
@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
}
Or you can map your data of some entity tables to second different entity, and reuse the NaturalId
behaviours provided by hibernate, i.e.
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
is used only for administrative situations, when it is required to change the owner
. And all the rest of code is kept as it is.
But be warned: you will have complex issues with caches (you have to create proper invalidation strategies for your caches, once changes in SomeEntityForAdmin
or SomeEntity
happend), and it becomes a complete mess when in same transaction both SomeEntity
and SomeEntityForAdmin
are involved.