我的应用程序出了问题。我想使用@PreUpdate& @PrePersist在更新或创建条目之前计算一些字段。这种方法像这样:
@PreUpdate
public void recount(){
if (applications != null){
this.appAssigned = getAssignmentCount();
this.appWaiting = getOutstandingCount();
}
}
@PrePersist
public void count(){
if (applications != null){
this.appAssigned = getAssignmentCount();
this.appWaiting = getOutstandingCount();
}
}
整个应用程序编译时没有任何错误或警告,但是当我更新条目时,不会调用这些方法。我试图调试问题,只想我可以告诉那些方法,永远不会被调用。日志中没有信息,没有。
有人有任何想法吗?
修改
这个实体有一些基本字段,很少有集合提取懒惰。这个方法有一个工作 - 在更新实体之前我需要根据那些延迟获取的集合重新计算某些东西。当然,我获取这些集合,更改内容,设置更改的集合,然后想要合并。不调用@Pre方法,但实体合并没有任何问题,所有集合都被更改,没有错误。
有趣的事实!! 我在合并之前手动累了重新计算,所以我添加了一行:
myEntity.setAppAssigned(myEntity.getAssignmentCount());
entityMenager.merge(myEntity);
然后@Pre方法被解雇O.O. 我尝试使用哈希码和相同的方法,我尝试合并和持久化实体,没有任何作用,除了手动设置一个字段,然后方法被触发。谁能理解这个?
编辑2
这是我用来更改集合的方法:
public void doStuff(Long id, Long appId){
Entity entity = entityMenager.findAndFetchCollections(id);
Set<Foo> appList = entity .getApplications();
Foo foo = new foo();
//here I find Foo I want to change, and remove it from collection
Iterator<Foo> iterator = appList.iterator();
while (iterator.hasNext()){
foo = iterator.next();
if (foo.getId().equals(appId)){
iterator.remove();
break;
}
}
//do some stuff with found foo and add it back to collection, then set collection back to entity
foo.setFooDate(new Date());
foo.setFooStatus("PENDING");
foo.setFooIndex(fooCount + 1);
appList.add(foo);
entity.setFoo(appList);
entityMenager.merge(entity);
}
在这种情况下,不会调用方法。如果我在合并li之前添加:
entity.setFooWaiting(entity.getFooCount());
然后调用方法。我也尝试使用EntityListener,但它的工作方式与实体类中的方法相同。
答案 0 :(得分:1)
我想我知道发生了什么 - 来自@Magnilex的建议帮助我得到了它:
它看起来@PreUpdate和@PrePersist不将实体看作实体而是作为SQL映射 - 即使我在实体类中更新集合,我也不更新SQL表中的任何字段,这就是为什么这些方法是没有被调用。当我手动设置一个基本字段时,不仅存在于我的实体映射中,而且还存在于SQL表中的列中,只有这时hibernate将其视为“更改”并使用这些方法。
有意义吗?