0

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

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

我目前正在通过创建一个父@MappedSuperclass(抽象)BaseResult对象和一个 扩展BaseResult的AppleResultOrangeResult @Enitiy来解决这个问题。

我的问题是,鉴于下面的陈述,我如何改进/注释模型中的对象,以便在访问/保留它时不必对每个实例进行 instanceof 检查?现在这是我必须做的,以避免“baseresult 不存在”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在我的情况下它也是一个实体,但事实并非如此。

4

1 回答 1

1

你应该使用@Inheritance. 然后,保存就像这样简单:

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

使用哪种继承策略取决于您当前的数据库设计,但我猜您对每个子类都有一个表,因此如下所示:

@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
}
于 2017-04-23T21:20:15.890 回答