Thursday, December 25, 2008

Make your Hibernate data objects smart?

In a race to learn Hibernate and create products for my former job, I have found a simple way to make my Hibernate data objects smarter.
We all know th standard way to access the Hibernate session using the SessionHolder*.

This is a basic abstract class(shown below) that will add the .add(), .update() and .delete() methods to your data objects.

Just extend this class by your Hibernate DTO like this:
public class Address extends BaseData

And then just after populating the new Address object, you write address.add().

  1. public abstract class BaseData implements Serializable {
  2. public String add(){
  3. try{
  4. SessionHolder.currentSession().getSess().save(this);
  5. SessionHolder.currentSession().getSess().flush();
  6. }catch(Exception ex){
  7. SessionHolder.endSession();
  8. ex.printStackTrace();
  9. Messenger.addFatalMessage(ex.getMessage(),ex.getMessage());
  10. return StandardResults.FAIL;
  11. }
  12. return StandartResults.SUCCESS;
  13. }
  14. public String update(){
  15. try {
  16. SessionHolder.currentSession().getSess().update(this);
  17. SessionHolder.currentSession().getSess().flush();
  18. return StandartResults.SUCCESS;
  19. } catch (Exception ex) {
  20. SessionHolder.endSession();
  21. ex.printStackTrace();
  22. Messenger.addFatalMessage(ex.getMessage(),ex.getMessage());
  23. return StandardResults.FAIL;
  24. }
  25. }
  26. public String delete(){
  27. try {
  28. SessionHolder.currentSession().getSess().delete(this);
  29. SessionHolder.currentSession().getSess().flush();
  30. return StandartResults.SUCCESS;
  31. } catch (HibernateException ex) {
  32. SessionHolder.endSession();
  33. ex.printStackTrace();
  34. Messenger.addFatalMessage(ex.getMessage(),ex.getMessage());
  35. return StandardResults.FAIL;
  36. }
  37. }
  38. }


This particular class was designed to be used in a JSF web application. Hence, the return types for methods are String's and there is a reference to StandardResults and Messenger class.
Messenger class is a generic class to present the user with a message.
StandardResults is what it's name stands for.

Please note, this may be used in JSF tables and lists only in places where the data is changed rarely or not concurrently.
But placing this element in a column in a h:dataTable will work as intended:




Also on your edit form page, you may use it without any potential problems, like this:


And on your new entry form page similarly:


In the end this technique saves a lot of time, by removing the need to create add, update and remove mehtods in your JSF managed-beans for those simple and boring CRUD operations.

* - For those who don't: see here or in simple terms this thing holds the session for the current thread and context - in the example, the call SessionHolder.currentSession() is translated to HibernateUtil.getSessionFactory().getCurrentSession().

2 comments:

Anonymous said...

I don't think you should recommend this way of using hibernate: flushing your session after each save/update could really cause performance problems.

JAlexoid said...

Just to note, the flush call was needed for instances where one entity was mapped to a view.
This is not proffered, but rather a workaround for that case.