Hi all,
I'm submitting the beginnings of a patch for
https://mifos.dev.java.net/issues/show_bug.cgi?id=1533
>From the defect report, there is mention that HibernateUtil.closeSession()
isn't always being called.
So, to make this safe(r), I suggest using a transaction callback.

e.g.

before
-----------
Session session = HibernateUtil.getSessionTL();
try{
  //..doStuff
}
finally{
  HibernateUtil.closeSession(); //Note, sometimes this isn't called!
}
return item;


new usage
---------------

HibernateUtil.doTransaction(new SafeReturnTransaction<Item>{
  public Item execute(Session session){
    // ..doStuff
    return item;
 }
});


I tried out the usage of it in ApplicationConfiguration, and I managed to
remove a few lines of duplicated code in the process.
(I bulked up the tests to make sure I didn't break anything)

If this works for everyone, I can propagate this through the code

Feedback?

Regards

Steve Horgan
Index: /home/steve/eclipse/workspace/mifos/mifos/src/org/mifos/application/configuration/persistence/ApplicationConfigurationPersistence.java
===================================================================
--- /home/steve/eclipse/workspace/mifos/mifos/src/org/mifos/application/configuration/persistence/ApplicationConfigurationPersistence.java	(revision 12273)
+++ /home/steve/eclipse/workspace/mifos/mifos/src/org/mifos/application/configuration/persistence/ApplicationConfigurationPersistence.java	(working copy)
@@ -48,6 +48,7 @@
 import org.mifos.application.master.business.MifosLookUpEntity;
 import org.mifos.application.master.business.SupportedLocalesEntity;
 import org.mifos.framework.exceptions.PersistenceException;
+import org.mifos.framework.hibernate.SafeReturnTransaction;
 import org.mifos.framework.hibernate.helper.HibernateUtil;
 import org.mifos.framework.persistence.Persistence;
 import org.mifos.application.master.business.CustomFieldDefinitionEntity;
@@ -65,74 +66,59 @@
 	 * an ongoing transaction
 	 */
 	public List<MifosLookUpEntity> getLookupEntities(){
-		
-		List<MifosLookUpEntity> entities=null;
-		try
-		{
-		Session session = HibernateUtil.getSessionTL();
-		 entities = session.getNamedQuery(
-				NamedQueryConstants.GET_ENTITIES).list();
-		 
-			for (MifosLookUpEntity entity : entities) {
-				Set<LookUpLabelEntity> labels = entity.getLookUpLabels();
-				entity.getEntityType();
-				for (LookUpLabelEntity label : labels) {
-					 label.getLabelText();
-					 label.getLocaleId();
+		return HibernateUtil.doTransaction(new SafeReturnTransaction<List<MifosLookUpEntity>>(){
+			public List<MifosLookUpEntity> execute(Session session) {
+				List<MifosLookUpEntity> entities = session.getNamedQuery(NamedQueryConstants.GET_ENTITIES).list();
+				
+				for (MifosLookUpEntity entity : entities) {
+					Set<LookUpLabelEntity> labels = entity.getLookUpLabels();
+					entity.getEntityType();
+					for (LookUpLabelEntity label : labels) {
+						label.getLabelText();
+						label.getLocaleId();
+					}
 				}
+				return entities;
 			}
-		} finally {
-			HibernateUtil.closeSession();	
-		}
-		
-		return entities;
+		});
 	}
 
-	public List<LookUpValueEntity> getLookupValues(){
-		List<LookUpValueEntity> values=null;
-		try{
-		Session session = HibernateUtil.getSessionTL();
-		 values = session.getNamedQuery(
-				NamedQueryConstants.GET_LOOKUPVALUES).list();
-		 
-			for (LookUpValueEntity value : values) {
-				Set<LookUpValueLocaleEntity> localeValues = value
-						.getLookUpValueLocales();
-				value.getLookUpName();
-				for (LookUpValueLocaleEntity locale : localeValues) {
+	public List<LookUpValueEntity> getLookupValues() {
+		return HibernateUtil.doTransaction(new SafeReturnTransaction<List<LookUpValueEntity>>() {
+			public List<LookUpValueEntity> execute(Session session) {
+				List<LookUpValueEntity> values = session.getNamedQuery(
+						NamedQueryConstants.GET_LOOKUPVALUES).list();
 
-					 locale.getLookUpValue();
-					 locale.getLocaleId();
+				for (LookUpValueEntity value : values) {
+					Set<LookUpValueLocaleEntity> localeValues = value.getLookUpValueLocales();
+					value.getLookUpName();
+					for (LookUpValueLocaleEntity locale : localeValues) {
+						locale.getLookUpValue();
+						locale.getLocaleId();
+					}
 				}
-
+				return values;
 			}
+		});
 
-		}
-		finally{
-			HibernateUtil.closeSession();
-		}
-		return values;
 	}
 	// this method is used by Localization class to load all the supported locales to its cache
 	public List<SupportedLocalesEntity> getSupportedLocale(){
-		List<SupportedLocalesEntity> locales=null;
-		try {
-		Session session = HibernateUtil.getSessionTL();
-
-		 locales = session.getNamedQuery(
-				NamedQueryConstants.SUPPORTED_LOCALE_LIST).list();
-		 
-			for (SupportedLocalesEntity locale : locales) {
-				locale.getLanguage().getLanguageShortName();
-				locale.getCountry().getCountryShortName();
-				locale.getLocaleId();
-
+		return HibernateUtil.doTransaction(new SafeReturnTransaction<List<SupportedLocalesEntity>>() {
+			public List<SupportedLocalesEntity> execute(Session session) {
+				List<SupportedLocalesEntity> locales = session.getNamedQuery(
+							NamedQueryConstants.SUPPORTED_LOCALE_LIST).list();
+				
+				for (SupportedLocalesEntity locale : locales) {
+					locale.getLanguage().getLanguageShortName();
+					locale.getCountry().getCountryShortName();
+					locale.getLocaleId();
+				}
+				return locales;
 			}
-		} finally {
-			HibernateUtil.closeSession();
-		}
+		});
 		
-		return locales;
+		
 	}
 	
 	public void addCustomField(CustomFieldDefinitionEntity customField) throws PersistenceException {
Index: /home/steve/eclipse/workspace/mifos/mifos/src/org/mifos/framework/hibernate/helper/HibernateUtil.java
===================================================================
--- /home/steve/eclipse/workspace/mifos/mifos/src/org/mifos/framework/hibernate/helper/HibernateUtil.java	(revision 12273)
+++ /home/steve/eclipse/workspace/mifos/mifos/src/org/mifos/framework/hibernate/helper/HibernateUtil.java	(working copy)
@@ -51,6 +51,8 @@
 import org.mifos.framework.components.logger.MifosLogManager;
 import org.mifos.framework.exceptions.ConnectionNotFoundException;
 import org.mifos.framework.exceptions.HibernateProcessException;
+import org.mifos.framework.hibernate.SafeReturnTransaction;
+import org.mifos.framework.hibernate.SafeVoidTransaction;
 import org.mifos.framework.hibernate.factory.HibernateSessionFactory;
 import org.mifos.framework.persistence.SqlUpgrade;
 
@@ -239,6 +241,28 @@
 			getSessionHolder().setTranasction(null);
 		}
 
+		
+	}
+
+	public static <T> T doTransaction(SafeReturnTransaction<T> transaction) {
+		final Session session = HibernateUtil.getSessionTL();
+		try{
+			return transaction.execute(session);
+		}
+		finally{
+			HibernateUtil.closeSession();
+		}
+	}
+
+	public static void doTransaction(SafeVoidTransaction transaction) {
+		final Session session = HibernateUtil.getSessionTL();
+		try{
+			transaction.execute(session);
+		}
+		finally{
+			HibernateUtil.closeSession();
+		}
 	}
 
+	
 }
Index: /home/steve/eclipse/workspace/mifos/mifos/src/org/mifos/framework/hibernate/SafeReturnTransaction.java
===================================================================
--- /home/steve/eclipse/workspace/mifos/mifos/src/org/mifos/framework/hibernate/SafeReturnTransaction.java	(revision 0)
+++ /home/steve/eclipse/workspace/mifos/mifos/src/org/mifos/framework/hibernate/SafeReturnTransaction.java	(revision 0)
@@ -0,0 +1,7 @@
+package org.mifos.framework.hibernate;
+
+import org.hibernate.Session;
+
+public interface SafeReturnTransaction<T> {
+	public T execute(Session session);
+}
Index: /home/steve/eclipse/workspace/mifos/mifos/src/org/mifos/framework/hibernate/SafeVoidTransaction.java
===================================================================
--- /home/steve/eclipse/workspace/mifos/mifos/src/org/mifos/framework/hibernate/SafeVoidTransaction.java	(revision 0)
+++ /home/steve/eclipse/workspace/mifos/mifos/src/org/mifos/framework/hibernate/SafeVoidTransaction.java	(revision 0)
@@ -0,0 +1,7 @@
+package org.mifos.framework.hibernate;
+
+import org.hibernate.Session;
+
+public interface SafeVoidTransaction {
+	public void execute(Session session); 
+}
Index: /home/steve/eclipse/workspace/mifos/mifos/test/org/mifos/application/configuration/TestApplicationConfigurationPersistence.java
===================================================================
--- /home/steve/eclipse/workspace/mifos/mifos/test/org/mifos/application/configuration/TestApplicationConfigurationPersistence.java	(revision 12273)
+++ /home/steve/eclipse/workspace/mifos/mifos/test/org/mifos/application/configuration/TestApplicationConfigurationPersistence.java	(working copy)
@@ -3,6 +3,7 @@
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Comparator;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Set;
 
@@ -17,6 +18,7 @@
 import org.mifos.application.master.business.LookUpValueEntity;
 import org.mifos.application.master.business.LookUpValueLocaleEntity;
 import org.mifos.application.master.business.MifosLookUpEntity;
+import org.mifos.application.master.business.SupportedLocalesEntity;
 import org.mifos.framework.MifosTestCase;
 import org.mifos.framework.components.configuration.util.helpers.ConfigConstants;
 import org.mifos.framework.hibernate.helper.HibernateUtil;
@@ -54,9 +56,35 @@
 			}
 		}
 
+		assertFalse(HibernateUtil.isSessionOpen());
 	}
+	
 	public void testGetLookupValues(){
-		assertNotNull(configurationPersistence.getLookupValues());
+		List<LookUpValueEntity> lookupValues = configurationPersistence.getLookupValues();
+		assertNotNull(lookupValues);
+		for (LookUpValueEntity lookupValueEntity : lookupValues) {
+			if (lookupValueEntity.getLookUpName().equals("SAVINGS_CLOSED")) {
+				Set<LookUpValueLocaleEntity> locales = lookupValueEntity.getLookUpValueLocales();
+				assertEquals(1, locales.size());
+				assertEquals("Closed", ((LookUpValueLocaleEntity)locales.toArray()[0]).getLookUpValue());
+			}
+			assertNotNull(lookupValueEntity.getLookUpId());
+		}
+		assertFalse(HibernateUtil.isSessionOpen());
+	}
+	
+	public void testGetSupportedLocales() throws Exception {
+		List<SupportedLocalesEntity> supportedLocales = configurationPersistence.getSupportedLocale();
+		assertNotNull(supportedLocales);
+		for (SupportedLocalesEntity supportedLocale : supportedLocales) {
+			if (supportedLocale.getLocaleId() == 1) {
+				assertEquals("EN", supportedLocale.getLocaleName());
+				assertEquals(1, supportedLocale.getDefaultLocale().intValue());
+				assertEquals("English", supportedLocale.getLanguage().getLanguageName());
+				assertEquals("EN", supportedLocale.getLanguage().getLanguageShortName());
+			}
+		}
+		assertFalse(HibernateUtil.isSessionOpen());
 	}
 	
 	/*
Index: /home/steve/eclipse/workspace/mifos/mifos/test/org/mifos/framework/hibernate/HibernateTest.java
===================================================================
--- /home/steve/eclipse/workspace/mifos/mifos/test/org/mifos/framework/hibernate/HibernateTest.java	(revision 12273)
+++ /home/steve/eclipse/workspace/mifos/mifos/test/org/mifos/framework/hibernate/HibernateTest.java	(working copy)
@@ -4,6 +4,7 @@
 
 import junitx.framework.ObjectAssert;
 
+import org.hibernate.Session;
 import org.mifos.framework.MifosTestCase;
 import org.mifos.framework.exceptions.HibernateStartUpException;
 import org.mifos.framework.hibernate.factory.HibernateSessionFactory;
@@ -50,4 +51,46 @@
 		assertFalse(HibernateUtil.isSessionOpen());
 	}
 
+	public void testSafeReturnTransactionReturnsValue() throws Exception {
+		Integer transactionResult = HibernateUtil.doTransaction(new SafeReturnTransaction<Integer>(){
+			public Integer execute(Session session){
+				return 123;
+			}
+		});
+		
+		assertNotNull(transactionResult);
+		assertEquals(123, transactionResult.intValue());		
+	}
+
+	public void testSafeReturnTransactionOpensAndClosesSession() throws Exception {
+		assertFalse(HibernateUtil.isSessionOpen());
+		try{
+			HibernateUtil.doTransaction(new SafeReturnTransaction<Integer>(){
+				public Integer execute(Session session){
+					assertTrue(HibernateUtil.isSessionOpen());
+					throw new RuntimeException("I am a crash test dummy");
+				}
+			});			
+			fail("This should have thrown an exception");
+		}
+		catch(RuntimeException e){
+			assertFalse(HibernateUtil.isSessionOpen());
+		}
+	}
+	
+	public void testSafeVoidTransactionOpensAndClosesSession() throws Exception {
+		assertFalse(HibernateUtil.isSessionOpen());
+		try{
+			HibernateUtil.doTransaction(new SafeVoidTransaction(){
+				public void execute(Session session){
+					assertTrue(HibernateUtil.isSessionOpen());
+					throw new RuntimeException("I am a crash test dummy");
+				}
+			});			
+			fail("This should have thrown an exception");
+		}
+		catch(RuntimeException e){
+			assertFalse(HibernateUtil.isSessionOpen());
+		}
+	}
 }
-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/

Reply via email to