绝大多数是不可变的NaturalId

时间:2016-09-28 12:48:04

标签: hibernate natural-key

我有一个简单的

public class SomeEntity {
    @Id private Integer id;
    @NaturalId private User owner;
    @NaturalId(mutable=true) private String name;
    ...
}

并且自然id创建一个唯一的键(好!),它使owner从hibernate不可变。这也是一件好事,但是,一旦在蓝色的月亮,管理员需要改变所有者。所以我似乎被迫使它也变得可变,这实在是不喜欢。

我可以使用普通的SQL来克服它,但这意味着撒谎,我也不喜欢撒谎,因为它可以欺骗休眠做错事。

我正在寻找一种干净的方式来陈述类似“不可变的东西,除非我说”(虽然我对它是可能的悲观)。我也很好奇,替代方案的缺点是什么。

1 个答案:

答案 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。所有其余的代码都保持不变。

但是请注意:缓存会遇到复杂的问题(一旦SomeEntityForAdminSomeEntity发生变化,您必须为缓存创建适当的失效策略),当它发生变化时,它会变得完全混乱在同一交易中,涉及SomeEntitySomeEntityForAdmin