Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Yet Another Robust Way to Listen to Hibernate Events

DZone's Guide to

Yet Another Robust Way to Listen to Hibernate Events

How to use some of the great new interfaces in Hibernate 4.

· Big Data Zone ·
Free Resource

Hortonworks Sandbox for HDP and HDF is your chance to get started on learning, developing, testing and trying out new features. Each download comes preconfigured with interactive tutorials, sample data and developments from the Apache community.

We often have a use case where we need to do something extra before or after Hibernate DML operations.

The reason why I am writing this article is because I spent hours trying to figure out the best way to deal with this sort of situation. My problem was that my entities were defined in XML, otherwise I could simply use hibernate annotations like @PreUpdate or @PreInsert to that fun stuff.

Hibernate 4 introduced the following amazing interfaces that made my life simple:

  • PostCommitInsertEventListener
  • PostCommitUpdateEventListener
  • PostCommitDeleteEventListener

Similarly, we have some preEvent listeners:

  • PreInsertEventListener
  • PreUpdateEventListener
  • PreDeleteEventListener

In my use case, I was supposed to provide some extra piece of functionality when entities are inserted, updated, or deleted from the database and the transaction is really committed. If a transaction is rolled back for any reason, I was not interested in doing anything extra.

So this is how I solved the problem.

We simply create a class, something like this that implements the above Post* interfaces:

@Component
public class CRUDEventListener implements PostCommitInsertEventListener, PostCommitUpdateEventListener, PostCommitDeleteEventListener {

  @Override
  public boolean requiresPostCommitHanding(EntityPersister persister) {
    // We must need to return true otherwise we would not be able to receive events
    return true;
  }

  @Override
  public void onPostDeleteCommitFailed(PostDeleteEvent event) {
    // Here we can do something useful, may be log or notify some external system
  }

  @Override
  public void onPostUpdateCommitFailed(PostUpdateEvent event) {
    // Here we can do something useful, may be log or notify some external system
  }

  @Override
  public void onPostInsertCommitFailed(PostInsertEvent event) {
    // Here we can do something useful, may be log or notify some external system
  }

  @Override
  public void onPostInsert(PostInsertEvent event) {
    if (event.getEntity() instanceof MyEntityInterface) {
      // Yeah event.getEntity() yeilds my hibernate entity class
    }
  }

  @Override
  public void onPostUpdate(PostUpdateEvent event) {
    if (event.getEntity() instanceof MyEntityInterface) {
      // Yeah event.getEntity() yeilds my hibernate entity class
    }
  }

  @Override
  public void onPostDelete(PostDeleteEvent event) {
    if (event.getEntity() instanceof MyEntityInterface) {
    // Yeah event.getEntity() yeilds my hibernate entity class
    }
  }
}

Wait! This is not everything, there is one last mystery that we actually need to register our CRUDEventListener class during startup:

@Component
public class CRUDEventRegistration {

  @Autowired
  private SessionFactory sessionFactory;

  @Autowired
  private CRUDEventListener listener;

  @PostConstruct
  public void registerListeners() {
    EventListenerRegistry registry = ((SessionFactoryImpl) sessionFactory).getServiceRegistry().getService(EventListenerRegistry.class);
    registry.getEventListenerGroup(EventType.POST_COMMIT_INSERT).appendListener(listener);
    registry.getEventListenerGroup(EventType.POST_COMMIT_UPDATE).appendListener(listener);
    registry.getEventListenerGroup(EventType.POST_COMMIT_DELETE).appendListener(listener);
  }
}


And boom, it worked like a charm!

Hortonworks Community Connection (HCC) is an online collaboration destination for developers, DevOps, customers and partners to get answers to questions, collaborate on technical articles and share code examples from GitHub.  Join the discussion.

Topics:
hibernate ,listener ,spring ,callback ,event ,java

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}