EntityLIstener not called via OneToOne mapping with cascade

白昼怎懂夜的黑 提交于 2019-12-12 02:54:55

问题


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.

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.

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?

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

Here's the Form's relationship definition

@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
}

The Application looks like this:

@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
}

Here's the listener

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

回答1:


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.

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

public interface MasterForm {
    Application getApplication();
}

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());
}

This is working as expected.



来源:https://stackoverflow.com/questions/16718461/entitylistener-not-called-via-onetoone-mapping-with-cascade

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!