在自动触发的默认侦听器之前,激活Hibernate自定义事件侦听器

时间:2011-05-30 15:17:09

标签: java database hibernate spring listener

我创建了一个自定义的Hibernate事件监听器,扩展了org.hibernate.event.PreInsertEventListener。 自定义侦听器覆盖onPreInsert方法,并在使用DAO将其保存到DB中之前设置“Contact”实体的字段。

问题是,在侦听器为其赋值之前,该字段为null,并且在我的自定义侦听器之前自动触发默认的hibernate事件侦听器。当他们检查ddl时,他们会看到字段上的not-null约束,并在让我的自定义事件侦听器为字段赋值之前抛出空检查异常。 (当使用spring AOP而不是hibernate自定义侦听器时会发生同样的问题:默认的hibernate侦听器在我的aspect方法之前执行)

那么,有可能在知道我使用spring会话工厂的情况下调整hibernate监听器的触发顺序吗?

由于

2 个答案:

答案 0 :(得分:1)

恕我直言,你所做的是矫枉过正。您可以使用Interceptor

实现相同的目标

如果您已经知道这一点并且出于某些原因选择覆盖PreInsetEventListener(有兴趣知道),那么您需要从重写org.hibernate.event.def.AbstractSaveEventListener的默认实现开始。 例如,org.hibernate.event.def.DefaultSaveEventListener。

请参阅“AbstractSaveEventListener.performSaveOrReplicate”中发生Nullability和外键约束检查,并将EntityActions添加到操作队列中。这些操作在会话刷新期间执行,这是从EntityActions调用PreInsertEventListener时。

答案 1 :(得分:1)

我为您创建了一个为person实体创建数据历史记录的示例。希望它有所帮助。

我必须制作辅助界面

public interface DataHistoryAware {

    public DataHistory getDataHistory();

    public void setDataHistory(DataHistory dataHistory);
}

这是监听器实现

public class DataHistoryListener {
   @PrePersist
    public void setCreateDataHistory(DataHistoryAware model) {
        //set creationDate
        DataHistory dataHistory = model.getDataHistory() == null ? new DataHistory() : model.getDataHistory();
        dataHistory.setCreationDate(new Date());
        model.setDataHistory(dataHistory); 
    }
@PostUpdate
    public void setUpdateDataHistory(DataHistoryAware model) {
        DataHistory dataHistory = model.getDataHistory() == null ? new DataHistory() : model.getDataHistory();
        dataHistory.setLastModificationDate(new Date());
        model.setDataHistory(dataHistory);
    }
}

人员实体

@Entity
@EntityListeners(DataHistoryListener.class)
@Table(name="person")
public class Person implements Serializable, DataHistoryAware {

@Column(name = "full_name", length = 255, nullable = false)
    private String fullName;

@OneToOne(cascade = CascadeType.PERSIST)
@JoinColumn(name = "data_history_id", nullable = false)
private DataHistory dataHistory;

public String getFullName() {
        return this.fullName;
    }

    public void setFullName(String fullName) {
        this.fullName = fullName;
    }
public DataHistory getDataHistory() {
        return dataHistory;
    }

    public void setDataHistory(DataHistory dataHistory) {
        this.dataHistory = dataHistory;
    }
}

此实现在持久化之前为person实体创建数据历史记录,并在合并之前更新它。 datahistory属性具有非null约束,因此这与您使用联系人实体的not-null属性的问题相同。希望它有用。