在dropwizard hibernate中自动更新实体上的创建/更新日期字段

在dropwizard hibernate中自动更新实体上的创建/更新日期字段,hibernate,event-listener,dropwizard,Hibernate,Event Listener,Dropwizard,我正在使用Dropwizard Hibernate(Hibernate 4)来持久化一些简单的实体 我的实体有一些属性,如“创建日期”、“修改日期”和“删除日期”。 我希望在保存/更新时自动填充/更新这些属性。 我希望这种逻辑在ORM级别,而不是DB级别。另外,另一方面,出于某些坚实的原因,我们正在管理自己的会议 现在的问题是dropwizard不支持Hibernate4的全部功能。它忽略@PrePersist和@PreUpdate 因此,我决定编写自己的自定义SaveOrUpdateEvent

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

我的实体有一些属性,如“创建日期”、“修改日期”和“删除日期”。
我希望在保存/更新时自动填充/更新这些属性。
我希望这种逻辑在ORM级别,而不是DB级别。另外,另一方面,出于某些坚实的原因,我们正在管理自己的会议

现在的问题是dropwizard不支持Hibernate4的全部功能。它忽略
@PrePersist
@PreUpdate

因此,我决定编写自己的自定义
SaveOrUpdateEventListener
,并将其注册到sessionFacotry的EventListener注册表中。然后我意识到Dropwizard确实提供了对EventListener注册表的访问。因此进入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; 

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

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

    .
    .
    .
}
@MappedSuperclass
@EntityListeners(value = { SaveOrUpdateDateListener.class })
public interface LastModifiable{
    public void setCreatedDate(Instant instant);
}
当我打印出已注册事件侦听器的列表时,我会在那里看到我的eventlistener。然而,当我试图保存或更新实体时,根本没有调用我的eventlistener。它只调用默认事件侦听器。 我已经看过了


因此,我还想知道是否有人在上面的Dropwizard链接中提出了任何解决方案的例子

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

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 5.3(Dropwizard 1.1)有所帮助。我不得不做了相当大的调整,但这是一个很好的起点。主要问题是,
JpaIntegrator
似乎已被删除,因此我必须实现自己的集成器:

public class EntityIntegrator implements Integrator {
    @Override
    public void integrate(final Metadata metadata,
                          final SessionFactoryImplementor sessionFactory,
                          final SessionFactoryServiceRegistry serviceRegistry) {
        final EventListenerRegistry eventListenerRegistry = serviceRegistry.getService(EventListenerRegistry.class);

        eventListenerRegistry.appendListeners(EventType.PRE_UPDATE, EventListener.class);
        eventListenerRegistry.appendListeners(EventType.PRE_INSERT, EventListener.class);
    }

    @Override
    public void disintegrate(final SessionFactoryImplementor sessionFactory,
                             final SessionFactoryServiceRegistry serviceRegistry) {
        // no-op
    }
}
public class EventListener implements PreUpdateEventListener, PreInsertEventListener {
    @Override
    public boolean onPreInsert(final PreInsertEvent event) {
        // your logic here
    }

    @Override
    public boolean onPreUpdate(final PreUpdateEvent event) {
        // your logic here
    }
}
然后在
/src/main/resources/META-INF/services/org.hibernate.integrator.spi.integrator
中:

your.package.here.EntityIntegrator
最后,实现integrator中引用的
EventListener
类:

public class EntityIntegrator implements Integrator {
    @Override
    public void integrate(final Metadata metadata,
                          final SessionFactoryImplementor sessionFactory,
                          final SessionFactoryServiceRegistry serviceRegistry) {
        final EventListenerRegistry eventListenerRegistry = serviceRegistry.getService(EventListenerRegistry.class);

        eventListenerRegistry.appendListeners(EventType.PRE_UPDATE, EventListener.class);
        eventListenerRegistry.appendListeners(EventType.PRE_INSERT, EventListener.class);
    }

    @Override
    public void disintegrate(final SessionFactoryImplementor sessionFactory,
                             final SessionFactoryServiceRegistry serviceRegistry) {
        // no-op
    }
}
public class EventListener implements PreUpdateEventListener, PreInsertEventListener {
    @Override
    public boolean onPreInsert(final PreInsertEvent event) {
        // your logic here
    }

    @Override
    public boolean onPreUpdate(final PreUpdateEvent event) {
        // your logic here
    }
}

观众:要使上述更改生效,请在pom或gradle中添加hibernate entitymanager。