当使用.save()或.update()而非.saveOrUpdate()时,自己的Hibernate DefaultSaveOrUpdateEventListener不会被触发。

4

我正在尝试构建一个基于Spring(3.1)和Hibernate(3.6.10)的Web应用程序,并且在Hibernate事件方面遇到了问题。

我编写了自己的DefaultSaveOrUpdateEventListener,用于更新/创建dateCreated和lastUpdated日期,在每个.saveOrUpdate()事件中都会调用它。目前为止一切顺利。

这个监听器不应该在.save()或.update()事件上也被调用吗?

监听器:

public class SaveOrUpdateDateListener extends DefaultSaveOrUpdateEventListener {

    private static final long serialVersionUID = 1L;

    private static Logger log = Logger.getLogger(SaveOrUpdateDateListener.class);


    @Override
    public void onSaveOrUpdate(SaveOrUpdateEvent event) {
        log.debug("Entered onSaveOrUpdate()");

        if (event.getObject() instanceof BaseDomain) {
            BaseDomain record = (BaseDomain) event.getObject();

            record.setDateUpdated(new Date());

            if (record.getDateCreated() == null) {
                record.setDateCreated(new Date());
            }
        }

        super.onSaveOrUpdate(event);
    }
}

Hibernate配置(部分):

<sesssion-factory>

<event type="save-update">
            <listener class="net.test.listener.hibernate.SaveOrUpdateDateListener"/>
            <listener class="org.hibernate.event.def.DefaultSaveOrUpdateEventListener"/>
        </event>    
</session-factory>

示例dao方法(不起作用):

@Autowired
private SessionFactory sessionFactory;


@Override
public void add(Registration registration) {
    sessionFactory.getCurrentSession().save(registration);
}

@Override
public void update(Registration registration) {
    sessionFactory.getCurrentSession().update(registration);
}

示例 dao 方法 (可用):

@Autowired
private SessionFactory sessionFactory;


@Override
public void add(Registration registration) {
    sessionFactory.getCurrentSession().saveOrUpdate(registration);
}

@Override
public void update(Registration registration) {
    sessionFactory.getCurrentSession().saveOrUpdate(registration);
}



编辑

在我决定不通用使用saveOrUpdate之后,我希望通过使用以下基类解决我的问题:

@MappedSuperclass
public class BaseDomain {

    @Id
    @GeneratedValue
    protected Integer id;

    @Column(nullable=false)
    protected Timestamp dateCreated;

    @Column(updatable = false, insertable = false, columnDefinition = "timestamp default current_timestamp on update current_timestamp")
    @Generated(GenerationTime.ALWAYS)
    protected Timestamp dateUpdated;


    protected BaseDomain() {
        this.dateCreated = new Timestamp(System.currentTimeMillis());
    }

    public Integer getId() {
        return id;
    }

    protected void setId(Integer id) {
        this.id = id;
    }

    public Timestamp getDateCreated() {
        return dateCreated;
    }

    public Date getDateUpdated() {
        return dateUpdated;
    }
}

由于当前时间戳只能在表格中使用一次(mysql限制),因此我尝试通过构造函数来构建dateCreated。

1个回答

6

只有调用saveOrUpdate方法才会触发保存或更新事件。Save-update不是save、update和saveOrUpdate的某种组合。

文档中,它被描述为:

14.2. 事件系统
...
Session接口的所有方法都与一个事件相关联。
...
当对这些方法之一进行请求时,Hibernate Session会生成适当的事件,并将其传递给该类型的配置事件侦听器。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接