[英]Automatically updating created/updated date field on the entity in dropwizard hibernate
我正在使用 Dropwizard Hibernate ( hibernate 4) 来持久化一些简单的实体。
我的实体有一些属性,如“created_date”、“modified_date”和“deleted_date”。
我希望这些属性在保存/更新时自动填充/更新。
我希望在 ORM 级别而不是在数据库上拥有该逻辑。 此外,另一方面,出于一些可靠的原因,我们正在管理自己的会议。
现在的问题是 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;
.
.
.
}
这是我的实体类的超类:
@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 5.3 (Dropwizard 1.1) 我不得不相当显着地调整yunspace 的答案,但这是一个很好的起点。 主要问题是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
}
}
然后在/src/main/resources/META-INF/services/org.hibernate.integrator.spi.Integrator
:
your.package.here.EntityIntegrator
最后,实现集成器中引用的EventListener
类:
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
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.