未通过具有级联的OneToOne映射调用EntityLIstener [英] EntityLIstener not called via OneToOne mapping with cascade

查看:91
本文介绍了未通过具有级联的OneToOne映射调用EntityLIstener的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Application对象和一些Form对象.每次保存表单时,我都想更新Application.lastUpdated.应用程序有一个EntityListener,我想用来为我设置Application.lastUpdated.

I have an Application object and some Form objects. Each time a Form is saved, I would like to update Application.lastUpdated. Application has an EntityListener which I want to use to set Application.lastUpdated for me.

当我保存应用程序时,将调用EntityListener并且它可以工作.但是,当我保存表单时,不会调用EntityListener.我可以通过调试以及lastUpdated字段不变的事实看到这一点.该窗体与具有CascadeType.ALL的应用程序具有单向OneToOne关系.

When I save Application, the EntityListener is called and it works. However when I save Form the EntityListener is not called. I can see this via debugging and via the fact that the lastUpdated field does not change. The Form has a one-way OneToOne relationship with the Application with CascadeType.ALL.

我可以使该设置生效吗?如果没有,是否有比手动更好的方法 每次保存表单时更新Application.lastUpdated吗?

Can I make this setup work? If not, is there a better way of doing it than manually updating Application.lastUpdated each time I save a Form?

我正在使用Hibernate和HSQLDB支持的JPA.所有的注释都是JPA.

I'm using JPA backed by Hibernate and HSQLDB. All the annotations are JPA.

这是表单的关系定义

@Entity
public class CourseForm implements Serializable {

  private static final long serialVersionUID = -5670525023079034136L;

  @Id
  @GeneratedValue(strategy = GenerationType.AUTO)
  long id;

  @OneToOne(cascade = CascadeType.ALL)
  @JoinColumn(name = "application_fk")
  private Application application;
  //more fields
  //getters and setters
}

该应用程序如下所示:

@Entity
@EntityListeners({ LastUpdateListener.class })

public class Application implements Serializable {

  @Id
  @GeneratedValue(strategy = GenerationType.AUTO)
  long id;

  private LocalDateTime lastUpdate;


  //more fields

  Application() {
  }

  public LocalDateTime getLastUpdate() {
    return lastUpdate;
  }

  public void setLastUpdate(LocalDateTime lastUpdate) {
    this.lastUpdate = lastUpdate;
  }
  //getters and setters
}

这是听众

public class LastUpdateListener {
@PreUpdate
@PrePersist
public void setLastUpdate(Application application) {
    application.setLastUpdate(LocalDateTime.now());
}

推荐答案

我怀疑上述设置无效,因为Application对象实际上并未更改,因此这就是@prePersist和@PreUpdate不被调用的原因.

I suspect that the above setup doesn't work because the Application object is not actually changed, so that's why @prePersist and @PreUpdate don't get invoked.

我通过让每个Form都实现一个接口MasterForm来解决了这个问题:

I solved the problem by having each Form implement an interface MasterForm:

public interface MasterForm {
    Application getApplication();
}

然后,我将EntityListener移到每个Form上,并按如下所示直接更新Application:

Then I moved the EntityListener onto each Form and had it update the Application directly as follows:

public class LastUpdateListener {
@PreUpdate
@PrePersist
public void setLastUpdate(MasterForm form) {
    form.getApplication().setLastUpdate(LocalDateTime.now());
}

这按预期工作.

这篇关于未通过具有级联的OneToOne映射调用EntityLIstener的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆