1

我有一个简单的

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

并且自然 id 创建了一个唯一的密钥(好!),它使owner休眠状态不可变。这也是一件好事,然而,一旦在一个蓝月亮,管理员需要更改所有者。所以我似乎被迫让它也可变,这真的很不喜欢。

我可以使用简单的 SQL 来克服它,但这意味着撒谎,我也不喜欢这样,因为它可能会欺骗 hibernate 做错事。

我正在寻找一种干净的方式来陈述“除非我说是不变的”这样的东西(尽管我对它的可能感到悲观)。我也很好奇,替代品的缺点是什么。

4

1 回答 1

2

在我看来:这种情况表明所有者和名称不再是自然ID。它们只是属性,从服务级别可以不时更改,并且owner, name从业务级别的角度来看,具有唯一值对是有限制的。因此,“除非我说的是不可变的”情况应该在“业务”服务级别解决:即所有者变为可变的,并且在您的服务内部创建单独的方法来修改它,其他方法不应修改此属性。IE:

@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在涉及同一事务时会变得一团糟。SomeEntitySomeEntityForAdmin

于 2017-02-21T13:59:20.590 回答