【问题标题】:Modify entity before flush刷新前修改实体
【发布时间】:2012-12-12 08:01:34
【问题描述】:

是否可以在每次刷新到数据库之前更新某些列?我有modifiedOnmodifiedBy 列,并希望在每次数据库更新时更新它们,类似于数据库触发器。 JPA可以吗?

【问题讨论】:

    标签: java jpa triggers entitylisteners


    【解决方案1】:

    免责声明:以下内容仅适用于 Hibernate / JPA。

    您可以像这样使用 JPA 更新 modifiedOn 属性:

    public class Entity {
    
         private Date modifiedOn;
    
         @PreUpdate 
         @PrePersist
         public void updateModified() {
             modifiedOn = new Date();
         }
    }
    

    至于modifiedBy,它有点棘手,因为 JPA 规范不鼓励在生命周期回调方法中引用其他实体。此外,您还需要了解当前用户,这可能属于服务层。

    您可以像这样使用EntityListener(但是,这仍然使用回调方法)

    @Entity
    @EntityListeners({MyListener.class})
    public class MyEntity {
        Date modifiedOn;
        User modifiedBy;
        ...
    }
    

    EntityListener 中的一个:

    public class MyListener {
    
        CurrentUserProvider provider; // Implement this and make sure it is set
    
        @PreUpdate
        @PrePersist
        public void updateModifier(MyEntity entity) {
             entity.setModifiedOn(new Date());
             entity.setModifiedBy(provider.getCurrentUser());
        }
    }
    

    【讨论】:

    • 我读到它在我目前使用的 EclipseLink 中不起作用。见这里:stackoverflow.com/a/1877631/952135
    • 这就是我们在 JPA2.0+Hibernate+Spring 上的做法。不确定 EclipseLink 是否支持。
    • 我测试过,它在 EclipseLink 中不起作用。我认为这是eclipselink的一个错误,即使modifiedOn也不起作用,它应该根据JPA规范。 modifiedBy 在 Hibernate 中工作的事实是一个 Hibernate 扩展。我在使用 Hibernate(不使用 JPA)时了解 Hibernate 的一些内部结构,我认为您可以更改“this”对象的引用,但根据处理更新的顺序,更改其他对象可能无法正常工作。请说明这仅适用于 Hiberante,我会将您的答案标记为正确。
    【解决方案2】:

    显然 JPA 在规范中定义了实体回调,例如 @PrePersist、@PreUpdate。对规范的简单修订将为您提供更多详细信息

    【讨论】:

      猜你喜欢
      • 2014-12-02
      • 1970-01-01
      • 2011-02-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-02
      • 1970-01-01
      相关资源
      最近更新 更多