我有一个简单的
public class SomeEntity {
@Id private Integer id;
@NaturalId private User owner;
@NaturalId(mutable=true) private String name;
...
}
并且自然id创建一个唯一的键(好!),它使owner
从hibernate不可变。这也是一件好事,但是,一旦在蓝色的月亮,管理员需要改变所有者。所以我似乎被迫使它也变得可变,这实在是不喜欢。
我可以使用普通的SQL来克服它,但这意味着撒谎,我也不喜欢撒谎,因为它可以欺骗休眠做错事。
我正在寻找一种干净的方式来陈述类似“不可变的东西,除非我说”(虽然我对它是可能的悲观)。我也很好奇,替代方案的缺点是什么。
答案 0 :(得分:2)
在我的意见中:这种情况表明所有者和名字不再是天生的ids。它们只是属性,从服务级别可以不时更改,并且从业务级别的角度来看,具有唯一的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
}
或者您可以将某些实体表的数据映射到第二个不同的实体,并重用hibernate提供的NaturalId
行为,即
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
。