我有一个应用程序,它使用传入的消息,解析消息中存在的数据,然后将规则应用于该数据。在">规则"实体上,有一列用于区分规则的类型。
我想将规则的结果保留为单独的表或子类,具体取决于处理它们的规则类型。
我目前正在通过创建一个父@MappedSuperclass
(抽象)BaseResult 对象和一个扩展BaseResult的AppleResult和OrangeResult@Enitiy
来解决这个问题。
我的问题是,鉴于下面的语句,我如何改进/注释模型中的对象,以便在访问/持久化它时不必对每个实例进行实例检查?现在,这就是我必须做的,以避免"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
也是一个实体,但事实并非如此。
你应该使用@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
}