Need help with Hibernate? Read this first:
http://www.hibernate.org/ForumMailingli ... AskForHelp
Hibernate version: 2.0
Code between sessionFactory.openSession() and session.close(): yes
Full stack trace of any exception that occurs:
net.sf.hibernate.LazyInitializationException: Failed to lazily initialize a collection - no session or session was closed
at net.sf.hibernate.collection.PersistentCollection.initialize(PersistentCollection.java:209)
at net.sf.hibernate.collection.PersistentCollection.read(PersistentCollection.java:71)
at net.sf.hibernate.collection.Bag.iterator(Bag.java:256)
at com.bd.profit.pricing.reports.AbstractReportRow.getStatisticalData(AbstractReportRow.java:48)
at com.bd.profit.pricing.reports.statisticaldata.StatisticalDataReportRow.<init>(StatisticalDataReportRow.java:106)
at com.bd.profit.pricing.reports.statisticaldata.StatisticalDataReport.<init>(StatisticalDataReport.java:46)
at com.bd.profit.pricing.processes.Export.createReports(Export.java:84)
at com.bd.profit.pricing.processes.Export.start(Export.java:116)
at com.bd.profit.pricing.managers.ProcessManager$RunProcess.construct(ProcessManager.java:160)
at org.jdesktop.swing.utils.SwingWorker$2.run(Unknown Source)
at java.lang.Thread.run(Thread.java:595)
Name and version of the database you are using: Oracle 9i
Ok, this seems to be a re-occuring problem that no-one can answer. I have a swing app, that has a second thread to do long tedious retrievals so as not to tie up my gui.
I have a facade class that has a getAllProducts() method. This method implements a cache layer that looks similiar to this:
Code:
public List<Product> getAllProducts() {
if(allProducts == null) {
allProducts = new ArrayList<Product>();
allProducts = dao.getAllProducts();
}
return allProducts;
}
This enables me to only retrieve the products one time. Now, within my spawned thread that does long updates, I need to access these products similiar to:
Code:
for (MarketingResponsibility resp : facade
.getAllMarketingResponsibility()) {
try {
products = facade.getProducts(resp);
reports = createReports(products);
runExport(fileLocation + resp.getMktgRespDesc());
} catch (NoDataFoundException ndfe) {/**/
}
}
This is causing a lazilyinitialization error, and I don't undestand why because the session never gets closed.
Code:
private void runExport(String location) throws NoDataFoundException{
application.startSession();
// this is the call that spawns the new thread
processManager.runExport(false,location);
// this does some GUI stuff while the export is running
monitorProgress();
facade.deleteAllPriceImpactData();
facade.deleteAllPricesAndCostData();
application.endSession();
}
public int startSession() throws TransactionException {
try {
log.warn("getting session");
HibernateSession.currentSession(appContext);
return 1;
} catch (HibernateException he) {
log.error("cant get session");
throw new TransactionException();
}
}
public void endSession() throws TransactionException {
try {
log.warn("ending session");
HibernateSession.closeSession();
} catch (HibernateException he) {
log.error("cant close session");
throw new TransactionException();
}
}
here is how i am handling my sessions
Code:
public class Application {
public int startSession() throws TransactionException {
try {
log.warn("getting session");
HibernateSession.currentSession(appContext);
return 1;
} catch (HibernateException he) {
log.error("cant get session");
throw new TransactionException();
}
}
/**
*
* @return boolean
*/
public boolean isSessionOpen() {
return HibernateSession.isSessionOpen();
}
/**
*
* @throws TransactionException
*/
public void endSession() throws TransactionException {
try {
log.warn("ending session");
HibernateSession.closeSession();
} catch (HibernateException he) {
log.error("cant close session");
throw new TransactionException();
}
}
public class HibernateSession {
/**
*
*/
public static final ThreadLocal<Session> session = new ThreadLocal<Session>();
private static SessionFactory sessionFactory;
/**
* Get the current Session or create a new sesion is none exists
*
* @param appContext
* @return Session
* @throws HibernateException
*/
public static Session currentSession(ApplicationContext appContext)
throws HibernateException {
Session s = session.get();
if (s == null) {
sessionFactory = (SessionFactory) appContext
.getBean("sessionFactory");
s = sessionFactory.openSession();
session.set(s);
if (!TransactionSynchronizationManager.getResourceMap()
.containsKey(sessionFactory)) {
TransactionSynchronizationManager.bindResource(sessionFactory,
new SessionHolder(s));
}
}
return s;
}
/**
*
* @return boolean
*/
public static boolean isSessionOpen() {
return (session.get() != null);
}
/**
* Close the current Session
*
* @throws HibernateException
*/
public static void closeSession() throws HibernateException {
Session s = session.get();
session.set(null);
if (s == null)
System.err.println("big problem");
if (s != null) {
s.flush();
TransactionSynchronizationManager.unbindResource(sessionFactory);
SessionFactoryUtils.closeSessionIfNecessary(s, sessionFactory);
}
}
}
Any thoughts or suggestions would be a huge help
-Nick
http://www.nickchristy.blogspot.com[/code]