Hi All,
Been using Hibernate for about 2 weeks now and have run into the
following problem, hopefully someone out there knows what I'm doing
wrong. I've read the hibernate manual and checked the web for something
similar, but can't find anything like this, I must be doing something
stupid!
Before I describe the problem, I've read the FAQ at
http://www.hibernate.org/117.html#A20
"Hibernate throws: Flush during cascade is dangerous.
This almost always happens because you forgot to remove a deleted instance from an association with cascading save enabled. You should remove deleted objects from associations before flushing the session."
I haven't removed ANY objects, it's when I try to remove the parent of the objects I've created this happens,
Thanks in advance for any help with this, its wrecking my head!!!!
Bascally I create some objects persist them in a method, which is the
setUp of a JUnit Test.
I run a method which makes some changes to the objects after it
retrieves them from the DAO.
I use the JUnit tearDown() method to delete the objects, which then
throws the Exception, the test has passed, the contents are in the DB,
I've checked this by hand.
We have something like the following structure, with the domain objects:
Airline
Account
CardHolder
The xdoclet tags look like this:
/**
* @return
* @hibernate.set cascade="all" lazy="false"
* @hibernate.collection-key column="AIRLINE_ID"
* @hibernate.collection-one-to-many
class="com.universalred.domain.CardHolder"
* @todo should probably be a list
*/
Airline has a one to many relationship with CardHolder
/**
* @return
*
* @hibernate.one-to-one class="com.universalred.domain.Account"
cascade="all"
*/
/**
* @return
* @hibernate.many-to-one class="com.universalred.domain.Airline"
column="AIRLINE_ID" not-null="false"
*/
CardHolder has an one to one relationship with Account and many to one
with Airline
When we do a delete on Airline it give us the following exception:
com.universalred.dao.DAOException: net.sf.hibernate.HibernateException:
Flush during cascade is dangerous - this might occur if an object was
deleted and then re-saved by cascade
at
com.universalred.dao.hibernate.BaseDAOHibernate.delete(BaseDAOHibernate.
java:218)
at
com.universalred.dao.hibernate.AirlineDAOHibernate.delete(AirlineDAOHibe
rnate.java:46)
at
com.universalred.io.FileEventAdaptorTest.tearDown(FileEventAdaptorTest.j
ava:116)
at junit.framework.TestCase.runBare(TestCase.java:130)
at junit.framework.TestResult$1.protect(TestResult.java:106)
at junit.framework.TestResult.runProtected(TestResult.java:124)
at junit.framework.TestResult.run(TestResult.java:109)
at junit.framework.TestCase.run(TestCase.java:118)
at junit.framework.TestSuite.runTest(TestSuite.java:208)
at junit.framework.TestSuite.run(TestSuite.java:203)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTe
stRunner.java:392)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRun
ner.java:276)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRu
nner.java:167)
Caused by: net.sf.hibernate.HibernateException: Flush during cascade is
dangerous - this might occur if an object was deleted and then re-saved
by cascade
at
net.sf.hibernate.impl.SessionImpl.flush(SessionImpl.java:2001)
at net.sf.hibernate.impl.SessionImpl.save(SessionImpl.java:589)
at
net.sf.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:1187)
at net.sf.hibernate.engine.Cascades$3.cascade(Cascades.java:88)
at net.sf.hibernate.engine.Cascades.cascade(Cascades.java:258)
at net.sf.hibernate.engine.Cascades.cascade(Cascades.java:341)
at
net.sf.hibernate.impl.SessionImpl.preFlushEntities(SessionImpl.java:2285
)
at
net.sf.hibernate.impl.SessionImpl.flushEverything(SessionImpl.java:2015)
at
net.sf.hibernate.impl.SessionImpl.flush(SessionImpl.java:2004)
at
com.universalred.dao.hibernate.BaseDAOHibernate.delete(BaseDAOHibernate.
java:214)
... 12 more
I use this method given below to delete Objects, would it be possible
that the ses.delete(obj) method has started some thread that hasn't
finished?
protected synchronized void delete(Object obj) throws DAOException {
Session ses = null;
try {
ses = ThreadLocalSession.currentSession();
if (ses == null) {
throw new DAOException("No Session.");
}
ses.delete(obj);
ses.flush();
} catch (Exception e) {
throw new DAOException(e);
}
This is the method I use to save:
/**
* Save the given domain object to the database.
*
* @param obj
* @throws DAOException
*/
protected synchronized void save(Object obj) throws DAOException {
Session ses = null;
try {
ses = ThreadLocalSession.currentSession();
ses.saveOrUpdate(obj);
// @TODO remove this flush if it is not needed
ses.flush();
} catch (Exception e) {
try {
ses.connection().rollback();
} catch (Exception ex) {
e.printStackTrace();
};
throw new DAOException(e);
}
}