我们遇到了一个问题,我们必须维护一个日期字段 - 并且最好保持其值 - 日期字段依赖于其他实体的状态。用JPA2 + Hibernate + Spring解决这个问题的正确方法是什么?
基本上,我们有三个实体,我们称之为Parent
,Child
和Conf
。 dependentDate
由依赖于其他实体状态的复杂业务规则计算。具体来说,它应该是Parent#date
减去Conf#delay
跳过周末或假期的所有日子(持久数据)。
问题是每当Parent#date
发生变化时,都应重新计算所有孩子的dependentDate
。每当Child
对象的conf
发生更改时,也会发生这种情况。目前,有一种服务方法可以根据Child
对象的关系计算新日期(让我们称之为calculateDate()
)。
我们面临的问题是应该计算字段的值。我提出了三种可能的解决方案。哪些 - 或者可能是其他 - 是更新依赖于其他实体状态的实体字段的首选方式?
EntityListener
calculateDate()
方法以下示例显示了省略注释配置的实体关系。
实体
public class Parent {
LocalDate date;
Set<Child> children; // one-to-many
}
public class Conf {
int delay;
}
public class Child {
LocalDate dependentDate;
Conf conf; // many-to-one
Parent parent; // many-to-one
}
答案 0 :(得分:2)
依赖于多个实体状态的复杂业务规则属于服务层。在应用程序中应该没有太多地方改变父母的日期和孩子的conf,所以你不应该有很多地方必须进行新的日期计算。
如果您真的有这么多地方,那么您可以明确指出必须通过将ChildDateUpdater实例(ChildDateUpdater作为接口)传递给父日期的设置者和子项的setter来重新计算日期CONF。这将明显表示每次更改这两个字段时都必须执行某些操作:
在家长中:
public void setDate(Date date, ChildDateUpdater childDateUpdater) {
this.date = date;
for (Child child : children) {
childDateUpdater.updateChildDate(child);
}
}
在孩子:
public void setConf(Conf conf, ChildDateUpdater childDateUpdater) {
this.conf = conf;
childDateUpdater.updateChildDate(this);
}
答案 1 :(得分:0)
在DAO中封装您的数据访问。如果要保存Parent
,请检查其值是否有任何更改,如果是,请相应地更新子项。
realsim
的触发选项也是可行的(基本上它是在不同级别实现的相同的想法)但是你会丢失可移植性(并且还会出现已经加载的子实例不存在的问题更新)。