我正在使用 Dropwizard Hibernate ( hibernate 4) 来持久化一些简单的实体。

我的实体有一些属性,如“created_date”、“modified_date”和“deleted_date”。
我希望这些属性在保存/更新时自动填充/更新。
我希望在 ORM 级别而不是在数据库上拥有该逻辑。此外,另一方面,出于一些可靠的原因,我们正在管理自己的 session 。

现在的问题是 dropwizard 不支持 hibernate 4 的全部功能。它忽略了 @PrePersist@PreUpdate
所以我决定编写自己的自定义 SaveOrUpdateEventListener 并将其注册到 sessionFacotry 的 EventListener Registry 中。然后我意识到 Dropwizard 确实提供了对 EventListener Registry 的访问。所以进入 dropwizard SessionFactoryFactory 类并修改它以访问 EventListener 注册表。
然后使用以下代码我试图注册我的事件监听器:

SessionFactory sessionFactory = hibernate.getSessionFactory();
EventListenerRegistry listenerRegistry = sessionFactory.getSessionFactoryOptions().getServiceRegistry().getService(EventListenerRegistry.class);
EventListenerGroup<SaveOrUpdateEventListener> evlg = listenerRegistry.getEventListenerGroup(EventType.SAVE_UPDATE);
evlg.appendListener(new SaveOrUpdateDateListener());

这是我的事件监听器:
public class SaveOrUpdateDateListener extends DefaultSaveOrUpdateEventListener{

    private static final Logger logger = LoggerFactory.getLogger(SaveOrUpdateDateListener.class);

    @Override
    public void onSaveOrUpdate(SaveOrUpdateEvent event) throws HibernateException{
        logger.info("onSaveOrUpdate is being called");
        if (event.getObject() instanceof LastModifiable) {
            LastModifiable record = (LastModifiable) event.getObject();
            record.setCreatedDate(Instant.now());
        }
        super.onSaveOrUpdate(event);
     }
}

这是我的实体类:
@Entity
@EntityListeners(value = { SaveOrUpdateDateListener.class })
@Table (name = "portfolio")
public class PortfolioBusiness implements LastModifiable, Serializable{

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id", nullable = false)
    private long id;

    @Column(name = "org_id", nullable = false)
    private long orgId;

    @Column(name = "subscription_id", nullable = false)
    private String subscriptionId;

    @Column(name="duns", nullable = false)
    private int duns;

    @Column(name="created_by", nullable = false)
    private long createdBy;

    @Column(name="created_date", nullable = false)
    @Convert(converter = InstantPersistenceConverter.class)
    private Instant createdDate;

    .
    .
    .
}

这是我的实体类的父类(super class):
@MappedSuperclass
@EntityListeners(value = { SaveOrUpdateDateListener.class })
public interface LastModifiable{
    public void setCreatedDate(Instant instant);
}

当我打印出已注册事件监听器的列表时,我会在那里看到我的事件监听器。但是,当我尝试保存或更新实体时,根本没有调用我的事件监听器。它只调用默认的事件监听器。
我已经看过这个
https://jira.spring.io/browse/SPR-9381

所以我也想知道是否有人有任何使用 Dropwizard 的上述链接中提出的解决方案的示例。

最佳答案

我们能够使用拦截器让 @PrePersist@PostPersist 工作:

public class DateTimeInterceptor {

    @PrePersist
    public void onPrePersist(Object entity) {
    }

    @PreUpdate
    public void onPreUpdate(Object entity) {
    }
}

在实体中注册拦截器:
@EntityListeners(value = {DateTimeInterceptor.class, PostInterceptor.class})

但是 最重要的 部分是您需要添加自定义配置文件:
/src/main/resources/META-INF/services/org.hibernate.integrator.spi.Integrator

其中包含一行:
org.hibernate.jpa.event.spi.JpaIntegrator

Dropwizard 版本是 0.8.1。试试看,希望这会有所帮助

关于hibernate - 在 dropwizard hibernate 中自动更新实体上的创建/更新日期字段,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/28310907/

10-11 23:44