Kostadin Slavkov
Kostadin Slavkov

Reputation: 88

Hibernate persist and error handling workflow

I'm prety new to hibernate and I have a question about the error handling and persistance workflow. I have the following piece of legacy code.

public void doPersist(Contact out){
  contactValidator.validationOne(out);
  entityManager.persist(out);
  contactValidator.validationTwo(out);
  contactValidator.validationThree(out);
}

ContactValidator is a class used to validate the Contact, it throws a multiple business exceptions in every validation method. I don't like how the method doPersist is constructed. Why it first calls entityManager.persist and then validate the object? In case of exception in some of the validation methods the data should be rollbacked. How Hibernate will rollback the data when persist is already called?

Upvotes: 1

Views: 998

Answers (1)

Naros
Naros

Reputation: 21113

I personally don't care for how the doPersist method is written either because I can see several cleaner alternatives that avoid having such a superfluous method.

To answer your specific question, the magic of rollback happens because of how transactions work. A transaction is nothing more than a series of operations that are performed as a single unit of work that must adhere to being atomic, consistent, isolated, and durable (e.g. ACID).

While the transaction is active and has yet to be committed, if an exception is thrown, then the exception handling tells the transaction to forget about what it was told to do.

Session session = sessionFactory.openSession();
try {
  session.getTransaction().begin();
  // do whatever work you want to do here
  session.getTransaction().commit();
}
catch ( Throwable t ) {
  if ( session.getTransaction().isActive() ) {
    session.getTransaction().rollback();
  }
  throw t;
}
finally {
  session.close();
}

So in this code, even if the transaction is attempting to commit and an exception is thrown, the catch clause sees that it is active and rolls the transaction back, thus telling the database to throw away all the work it was just asked to perform.

Now I want to touch on your ContactValidator.

My guess is that your ContactValidator closely aligned with how Bean Validation. It basically looks at the bean's state and makes sure that there aren't any inconsistent expectations and if so, assert with an exception.

When using hibernate-validator in conjunction with hibernate-core, you get bean validation automatically for free because Hibernate will plug into the validator framework and perform validate operations for the following events

  • PrePersistEvent
  • PreUpdateEvent
  • PreRemoveEvent

As you can see, there isn't any post event support out of the box. That makes sense because you generally want to satisfy constraints before you actually save or update a database row. This is why I find your second and third contact validation methods strange.

That aside, if you really need some post-insert or post-update validation, you can easily tie into the existing bean validator listener for these operations too with a custom Hibernate listener which you register on the PostInsertEvent and PostUpdateEvent groups to call bean validation.

Upvotes: 1

Related Questions