Sleep Transaction Management with DAO Design Pattern

I have many tables. For each table, we have a DAO interface and a DAOImplementation class.

DAO Interface Example

public interface CancelPolicyDAO { public CancelPolicy insertCancelPolicy(CancelPolicy cpdao)throws ChannelDispatcherException; public CancelPolicy updateCancelPolicy(CancelPolicy cpdao)throws ChannelDispatcherException; public void deleteCancelPolicy(CancelPolicy cpdao)throws ChannelDispatcherException; public CancelPolicy findByCancelPolicyData(Integer id, Integer offSetUM, Integer nights, Float pOrAm, Byte isPercent)throws ChannelDispatcherException; public CancelPolicy findByCancelPolicyId(Integer id)throws ChannelDispatcherException; } 

Example Class DAOImplementation

 public class CancelPolicyDAOImpl implements CancelPolicyDAO { @Override public CancelPolicy insertCancelPolicy(CancelPolicy bean) throws ChannelDispatcherException { Session ses = null; try { ses = HibernateConnector.getInstance().getSession(); ses.save(bean); ses.flush(); return bean; } catch (Exception e) { e.printStackTrace(); throw new ChannelDispatcherException(DbUtil.getStackTraceMessage(e)); } finally { if (ses != null) { try { ses.close(); } catch (Exception er) { er.printStackTrace(); } } } } @Override public CancelPolicy updateCancelPolicy(CancelPolicy bean) throws ChannelDispatcherException { Session sess = null; try { sess = HibernateConnector.getInstance().getSession(); sess.update(bean); sess.flush(); return bean; } catch (Exception e) { e.printStackTrace(); throw new ChannelDispatcherException(DbUtil.getStackTraceMessage(e)); } } @Override public void deleteCancelPolicy(CancelPolicy bean) throws ChannelDispatcherException { Session sess = null; try { sess = HibernateConnector.getInstance().getSession(); sess.delete(bean); sess.flush(); } catch (Exception e) { e.printStackTrace(); throw new ChannelDispatcherException(DbUtil.getStackTraceMessage(e)); } } @Override public CancelPolicy findByCancelPolicyData(Integer id, Integer offSetUM, Integer nights, Float pOrAm, Byte isPercent) throws ChannelDispatcherException { Session ses = null; try { ses = HibernateConnector.getInstance().getSession(); Query query = ses.createQuery("from CancelPolicy a where " + " a.cancelPolicyTypeId =:cancelPolicyTypeId " + " and a.offsetUnitMultiplier =:offsetUnitMultiplier " + " and a.nights =:nights " + " and a.percentOramount =:percentOramount " + " and a.isPercent =:isPercent"); query.setParameter("cancelPolicyTypeId", id); query.setParameter("offsetUnitMultiplier", (offSetUM)); query.setParameter("nights", (nights)); query.setParameter("percentOramount", pOrAm); query.setParameter("isPercent", isPercent); List queryList = query.list(); if (queryList != null && queryList.isEmpty()) { return null; } else { return (CancelPolicy) queryList.get(0); } } catch (Exception e) { e.printStackTrace(); throw new ChannelDispatcherException(DbUtil.getStackTraceMessage(e)); } finally { if (ses != null) { try { ses.close(); } catch (Exception e) { e.printStackTrace(); } } } } public CancelPolicy findByCancelPolicyId(Integer id) throws ChannelDispatcherException { Session ses = null; try { ses = HibernateConnector.getInstance().getSession(); Query query = ses.createQuery("from CancelPolicy a where " + " a.id =:id "); query.setParameter("id", id); List queryList = query.list(); if (queryList != null && queryList.isEmpty()) { return null; } else { return (CancelPolicy) queryList.get(0); } } catch ( Exception e) { e.printStackTrace(); throw new ChannelDispatcherException(DbUtil.getStackTraceMessage(e)); } finally { if (ses != null) { try { ses.close(); } catch (Exception e) { e.printStackTrace(); } } } } 

Basic Method Example

  public static void main(String[] args) { // How to handel Transaction in Hibernate ? CancelPolicyDAO cancelPolicyDAO = HibernateDAOFactory.getInstance().getCancelPolicyDAO(); CancelPolicy insertCancelPolicy = cancelPolicyDAO.findByCancelPolicyData(2, 76, 25, 25.36f, 3); if(insertCancelPolicy==null){ CancelPolicy cancelPolicy = new CancelPolicy(); cancelPolicy.setCancelPolicyTypeId(1); cancelPolicy.setNights(2); insertCancelPolicy = cancelPolicyDAO.insertCancelPolicy(cancelPolicy); } Integer autoIncrementId = insertCancelPolicy.getId(); AvailabilityDAO availabilityDAO = HibernateDAOFactory.getInstance().getAvailabilityDAO(); Availability availability = new Availability(); // using CancelPolicy autoIncrementId availability.setId(autoIncrementId); availability.setCount(2); availability.setMaxLos(5); availabilityDAO.insertAvailability(availability); . . . . . } 

Now my question is: how do I handle a transaction in DAOImpl? Should I pass a session object as a parameter to each DAOImpl or is there a better approach

+7
java design-patterns hibernate dao transactions
source share
4 answers

I highly recommend not reinventing the wheel; Use existing, reliable, and verified code.

The comments already mentioned AOP and Spring . This is the way. The Spring structure even has a subproject called Spring Data that allows you to define search methods (e.g. findByCancelPolicyData ) in a declarative way.

This will save you a lot of work.

If for some reason you do not want / cannot use Spring, you can still read the surprisingly good documentation of the basic framework and the mentioned Spring data to get a lot of great ideas regarding the transaction (through AOP), code reuse (through common DAOs ) or API design. Do not miss this.

+10
source share

When using Spring, probably the best way to add transaction management, you can still solve it even without re-factorizing your entire code base.

What you need to do is set up the following configuration:

 hibernate.current_session_context_class=thread 

You, DAO, must access the session through:

 [SessionFactory.getCurrentSession()][1]; 

You still need to declare the boundaries of the transactions at the service level:

 Session sess = factory.openSession(); Transaction tx = null; try { tx = sess.beginTransaction(); dao1.find(); dao2.save(entity); tx.commit(); } catch (RuntimeException e) { if (tx != null) tx.rollback(); throw e; } finally { sess.close(); } 

Both dao1 and dao2 will use the same Hibernate session and the same transaction.

To avoid this complicated transaction management code processing, you can write a simple TransactionManager utility, for example:

 pubic static abstract class TransactionCallable<T> { public abstract T execute(); } public class TransactionManager { pubic static <T> T doInTransaction(TransactionCallable<T> callable) { T result = null; Session session = null; Transaction txn = null; try { session = sf.openSession(); txn = session.beginTransaction(); result = callable.execute(); txn.commit(); } catch (RuntimeException e) { if ( txn != null && txn.isActive() ) txn.rollback(); throw e; } finally { if (session != null) { session.close(); } } return result; } } 

And here is what the service looks like:

 TransactionManager.doInTransaction(new TransactionCallable<Void>() { @Override public Void execute() { dao1.find(); dao2.save(entity); } }); 
+7
source share

If you have a web application and you are not using spring in your project for an mgmt session , I would suggest using an interceptor to separate the session processing logic outside of your DAO. You can link to the same article below. Note that there are certain CONs associated with this approach, but we have found that this is the most convenient way in our case.

Open Session in View Template

Below is an example of how we use Open Session in View with Generics for your class, which we may have,

  public class CancelPolicyDAOImpl extends GenericDAOImpl<CancelPolicy, Long> implements CancelPolicyDAO { @Override public CancelPolicy insertCancelPolicy(CancelPolicy bean) throws ChannelDispatcherException { try { // save method is implemented in GenericDAOImpl described below. return save(bean); } catch (Exception e) { e.printStackTrace(); } } //remaining methods } 

The above code saving method is used, which is implemented in GenericHibernateDAOImpl, as shown below. You can use Google for the GenericHibernateDAOImpl class and grab it, which has a number of additional methods for basic operations.

 public abstract class GenericDAOImpl<T, ID extends Serializable> { private Session session; public T save(final T entity) { Transaction trans = null; try { trans = session.beginTransaction(); session.saveOrUpdate(entity); session.flush(); trans.commit(); } catch (Exception ex) { rollBackTransaction(trans); // you might require to throw error again here } return entity; } //in case any complex operations required you can get core session object from this method protected Session getSession() { return sessionFactory.getCurrentSession(); } } 

Now back to your question about where to get the session, as shown above. A GenericHibernateDAOImpl session is retrieved from a singleton sessionFactory using the getCurrentSession method. Please note that you will need to activate an active transaction before receiving the current session, which you can make available in your interceptor (the link is provided at the beginning of this message).

Please let me know.

+2
source share

No need to use frameworks, the CancelPolicy object is the main object and must have a sleep mode function (cascade). Check out the link ( Cascading Life Cycle )

So, you fill in the CancelPolicy object with all the necessary relationships and say "save", it will save the entire schedule of related objects.

+1
source share

All Articles