【问题标题】:Fire Hibernate custom event listener before auto-triggered default listeners在自动触发的默认侦听器之前触发 Hibernate 自定义事件侦听器
【发布时间】:2011-05-30 15:17:09
【问题描述】:

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

问题是,在侦听器给它一个值之前该字段为空,默认休眠事件侦听器在我的自定义侦听器之前自动触发。当他们检查 ddl 时,他们会看到字段上的非空约束,并在让我的自定义事件侦听器为该字段提供其值之前抛出一个空检查异常。 (使用spring AOP而不是hibernate自定义监听器时会出现同样的问题:默认的hibernate监听器在我的方面方法之前执行)

那么,知道我使用的是 Spring 会话工厂,就可以调整休眠侦听器的触发顺序吗?

谢谢

【问题讨论】:

    标签: java database hibernate spring listener


    【解决方案1】:

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

    我必须制作一个帮助界面

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

    此实现在持久化之前为人员实体创建数据历史记录,并将在合并之前对其进行更新。 datahistory 属性具有非空约束,因此这与联系人实体的非空属性问题相同。希望有用。

    【讨论】:

    • 当dataHistory为null时,默认hibernate监听器不会在prepersist监听器被触发之前触发非空约束违反异常吗?
    • 它对我有用,所以我认为 prepersist 侦听器首先被解雇,然后是其他人。
    • lepike:我切换到 EntityManager 而不是 hibernate 的会话,并使用了你提到的 @PrePersist,它就像一个魅力!谢谢。
    【解决方案2】:

    恕我直言,你所做的太过分了。您可以使用Interceptor 实现相同的目标

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-09-06
      • 2015-12-18
      • 2013-05-19
      • 1970-01-01
      • 2021-01-14
      • 1970-01-01
      • 1970-01-01
      • 2017-01-05
      相关资源
      最近更新 更多