10

根据此处的文章,我正在使用 Hibernate 4.1 尝试调用 PreInsertEventListener 来更新实体,然后再将其插入数据库:http: //anshuiitk.blogspot.ca/2010/11/hibernate-pre-database-opertaion-event .html

public class PreInsertListener implements PreInsertEventListener {

    @Override
    public boolean onPreInsert(PreInsertEvent event) {
        Product product  = (Product)event.getEntity();
        String barcode = "B" + product.getProductId();
        product.setBarcode(barcode);

        // Update the state value that will be persisted
        String[] properties = event.getPersister().getEntityMetamodel().getPropertyNames();
        List<String> propertiesList = Arrays.asList(properties);
        event.getState()[propertiesList.indexOf('barcode')] = barcode;
    }
}

当我调试它时,它正在执行 PreInsertListener 代码,但插入数据库的值不包含代码的更改。这曾经在 Hibernate 3 中工作。我在这里缺少什么?

4

3 回答 3

8

只要确保您没有陷入您在上面分享的博客文章中列出的方法 3 问题。如果您在一个事务中对实体进行了插入和更新操作,那么您的 preInsert 侦听器操作将被更新操作覆盖。

-- 来自博文的消息 ( http://anshuiitk.blogspot.ca/2010/11/hibernate-pre-database-opertaion-event.html )

Hibernate 生成一个准备好的语句,并从事件中存在的“状态”数组中填充参数。因此,对这个“状态”数组所做的任何更改都会反映在休眠生成的 sql 语句中,最后反映在数据库中。插入和更新事件具有此状态数组的不同副本。

在预更新事件之前调用预插入侦听器(如果发生插入和更新)。当在同一个事务中创建、持久化并修改实体时,就会发生这种情况。这将导致两个单独的 sql 语句,第一个是插入语句,第二个是更新语句,在同一个实体上。使用插入语句,我们仅在insertUserandinsertTime中设置 andPreInsertEventListener而不是updateUserand updateTime。生成的语句看起来像

insert into entity (id, .... , insert_user, insert_time, update_user, update_time) values (1, .... 'test', '21.11.2010 16:10:00', null, null)

使用PreUpdateEventListener生成的更新 SQL 会像

update entity set id=1 .... , insert_user=null, insert_time=null, update_user='test', update_time='21.11.2010 16:10:00'
于 2015-05-05T22:38:09.533 回答
0

请改用 saveorupdate 事件侦听器。

于 2013-10-31T04:40:30.567 回答
0

事件监听器本身有一个返回值。这个返回值的作用是告诉 NHibernate 是否执行实际的插入/更新 SQL 查询。当您返回 false 时,它​​会执行它们。当您返回 true 时,它​​不会。这样,您可以抑制对数据库的实际持久性。

添加返回 false

于 2020-03-03T10:56:43.590 回答