Hibernate:如何建模继承类型结构并在没有显式转换的情况下进行操作

Hibernate: How to model an Inheritance type structure and do operations without explicit casting

我有一个应用程序可以使用传入消息、解析消息中存在的数据,然后将规则应用于该数据。在 Rule 实体上,有一列区分规则的 type

我想将规则的 结果 保留到 单独的表或子类 ,具体取决于 类型Rule 处理了它们。

我目前正在通过创建一个父 @MappedSuperclass(抽象)BaseResult 对象和一个 AppleResultOrangeResult @Enitiy 扩展了 BaseResult.

我的问题是,根据下面的陈述,我怎样才能 improve/annotate 我在模型中的对象,这样我就不必在转到 [=47= 时对每个实例进行 instanceof 检查] 它?现在这就是我必须要做的,以避免 "baseresult does not exist" SQL 语法异常:

public void save(BaseResult baseResult) {
    if (baseResult instanceof AppleResult) {
        jpaApi.em().merge((AppleResult) baseResult);
    } else if (baseResult instanceof OrangeResult) {
        jpaApi.em().merge((OrangeResult) baseResult);
    }
}

我希望有比必须执行 if/else 并根据结果显式转换更优雅的解决方案。我一直在研究使用泛型的 @DiscriminatorValue 注释之类的东西,但这些似乎都要求 BaseResult 在我的例子中也是一个实体,但事实并非如此。

你应该使用 @Inheritance。那么,保存就很简单了:

public void save(final BaseResult baseResult) {
    jpaApi.em().merge(baseResult);
}

使用哪种继承策略取决于您当前的数据库设计,但我猜您对每个子类都有一个 table,所以像这样:

@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class BaseResult {
    //...
}

@Entity
public class AppleResult extends BaseResult {
    //...
} 

在超类上有 @Entity 不是问题,反正它是 abstract..

此外,使用 merge 通常是不应该做的事情,您应该只在事务中操作您的实体,并且它会在事务提交时自动保存在数据库中:

@Transactional //either this...
public void doStuff(final ResultCommand command) {
    //begin transaction <-- ...or this
    final BaseResult result = em.find(BaseResult.class, command.getResultId());
    result.apply(command);
    //end transaction
}