Okay here is a really strange problem. I have included the extensive code, exception stack, etc below, but wanted to provide a synopsis up front. I have 4 main classes/entities: CopyJob, CopyRun, CopyTarget, CopySpec. CopyJob has a list of CopyRuns. CopyRun has a list of CopyTargets. CopyTargets has a list of CopySpecs. Each of these list has basically the exact same schema defintion (refer below): cascade=all and lazy=true with the one exception CopyJob->CopyRuns has inverse=true (the others have inverse=false).
There is a method getTotalCopies() that is a recursive call from CopyJob to CopyTarget (CopyJob.getTotalCopies loops over all CopyRuns and calls CopyRun.getTotalCopies() which loops over all CopyTargets and calls CopyTarget.getTotalCopies()). In a UI, when I go to display this stat, it makes this recursive call.
Here is the scenario:
1. If I create a CopyJob with no CopyRuns and go to access the "iterator" for the CopyRuns list during the conduct of the "getTotalCopies()" recursive call, then it gets back a valid iterator on the empty CopyRuns list.
2. If I create a CopyJob, add a CopyRun to it and go to access the iterator on the CopyTargets list duing the conduct of the "getTotalCopies" call, then it gets back a valid iterator on the empty CopyTargets list.
3. If I create a CopyJob, add a CopyRun, add a CopyTarget and go to access the iterator on the CopySpecs list during the conduct of the getTotalCopies call, then I get the ERROR.
Basically, when I inspect the list(s) during the run, all of them are initialized, except for the CopyTarget->CopySpecs list. I have even tried to force initialization on this list and it seems to still produce the error.
One issue that may be contributing to the problem... My "hibernate objects actually are wrappers around true POJO versions of the same object: HibCopyJob wraps POJOCopyJob. And the POJO's are where the data actually resides (including the list). Don't ask why, I just had to do this...
Rest below.
Hibernate version: 2.1.1
Mapping documents:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">
<hibernate-mapping>
<class name="com.gsk.legal.copy.bo.himpl.HIBCopyJob" table="COPY_JOB">
<id name="id" type="long" column="id">
<generator class="native"/>
</id>
<property name="name" column="NAME" type="string"/>
<bag name="copyRuns" table="COPY_JOB_COPY_RUNS_LIST"
cascade="all" lazy="true" inverse="true">
<key column="COPY_JOB_ID"/>
<one-to-many class="com.gsk.legal.copy.bo.himpl.HIBCopyRun"/>
</bag>
</class>
</hibernate-mapping>
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">
<hibernate-mapping>
<class name="com.gsk.legal.copy.bo.himpl.HIBCopyRun" table="COPY_RUN">
<id name="id" type="long" column="id">
<generator class="native"/>
</id>
<property name="name" column="NAME" type="string"/>
<property name="stateStr" column="STATE_STR" type="string"/>
<property name="runStartDateLong" column="RUN_START_DATE_L" type="long"/>
<property name="runEndDateLong" column="RUN_END_DATE_L" type="long"/>
<many-to-one name="parentCopyJob" class="com.gsk.legal.copy.bo.himpl.HIBCopyJob"
column="COPY_JOB_ID"/>
<bag name="copyTargets" table="COPY_RUN_COPY_TARGETS_LIST"
cascade="all" lazy="true" inverse="false">
<key column="COPY_RUN_ID"/>
<one-to-many class="com.gsk.legal.copy.bo.himpl.HIBCopyTarget"/>
</bag>
</class>
</hibernate-mapping>
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">
<hibernate-mapping>
<class name="com.gsk.legal.copy.bo.himpl.HIBCopyTarget" table="COPY_TARGET">
<id name="id" type="long" column="id">
<generator class="native"/>
</id>
<property name="URL" column="URL" type="string"/>
<many-to-one name="parentCopyRun" class="com.gsk.legal.copy.bo.himpl.HIBCopyRun"
column="COPY_RUN_ID"/>
<bag name="copySpecs" table="COPY_TARGET_COPY_SPECS_LIST"
cascade="all" lazy="true" inverse="false">
<key column="COPY_TARGET_ID"/>
<one-to-many class="com.gsk.legal.copy.bo.himpl.HIBCopySpec"/>
</bag>
</class>
</hibernate-mapping>
Code between sessionFactory.openSession() and session.close():
HIBCopyJob
-----------------------------------------------------------------------------
public class HIBCopyJob extends HIBDBObj implements CopyJob {
public boolean isDirty() {
return getPOJOCopyJob().isDirty();
}
public Object getPOJO() {
return getPOJOCopyJob();
}
public void setName(String name) {
getPOJOCopyJob().setName(name);
}
public String getName() {
return getPOJOCopyJob().getName();
}
public void addCopyRun(CopyRun cr) {
getCopyRuns().add(cr);
}
public void removeCopyRun(CopyRun cr) {
getCopyRuns().remove(cr);
}
public Iterator allCopyRuns() {
return getCopyRuns().iterator();
}
public CopyRun[] allCopyRunsAsArray() {
if(allCopyRunsSize() > 0) {
return (CopyRun[]) getCopyRuns().toArray(new CopyRun[allCopyRunsSize()]);
}
return new CopyRun[0];
}
public int allCopyRunsSize() {
return getCopyRuns().size();
}
public void setCopyRuns(List l) {
getPOJOCopyJob().setCopyRuns(l);
//copyRuns = l;
}
public List getCopyRuns() {
List l = getPOJOCopyJob().getCopyRuns();
if(!isInitialized(l)) {
initialize(l);
}
return l;
}
public int totalCopies() {
checkInitialized();
return getPOJOCopyJob().totalCopies();
}
public int totalCopyFailures() {
checkInitialized();
return getPOJOCopyJob().totalCopyFailures();
}
public int totalSizeKB() {
checkInitialized();
return getPOJOCopyJob().totalSizeKB();
}
public List allFailures() {
return getPOJOCopyJob().allFailures();
}
public void checkInitialized() {
List l = getPOJOCopyJob().getCopyRuns();
if(!isInitialized(l)) {
initialize(l);
}
}
private POJOCopyJob getPOJOCopyJob() {
if(pojoCopyJob == null)
pojoCopyJob = new POJOCopyJob();
return pojoCopyJob;
}
private POJOCopyJob pojoCopyJob;
private List copyRuns;
}
HIBCopyRun
-------------------------------------------------------------------------------
public class HIBCopyRun extends HIBDBObj implements CopyRun {
public Object getPOJO() {
return getPOJOCopyRun();
}
public void setName(String name) {
getPOJOCopyRun().setName(name);
}
public String getName() {
return getPOJOCopyRun().getName();
}
public void setState(CopyRunState crs) {
getPOJOCopyRun().setState(crs);
}
public CopyRunState getState() {
return getPOJOCopyRun().getState();
}
public void setParentCopyJob(CopyJob cj) {
getPOJOCopyRun().setParentCopyJob(cj);
}
public CopyJob getParentCopyJob() {
return getPOJOCopyRun().getParentCopyJob();
}
public void setRunStartDate(Calendar c) {
getPOJOCopyRun().setRunStartDate(c);
}
public Calendar getRunStartDate() {
return getPOJOCopyRun().getRunStartDate();
}
public void setRunEndDate(Calendar c) {
getPOJOCopyRun().setRunEndDate(c);
}
public Calendar getRunEndDate() {
return getPOJOCopyRun().getRunEndDate();
}
public void addCopyTarget(CopyTarget ct) {
getCopyTargets().add(ct);
}
public void removeCopyTarget(CopyTarget ct) {
getCopyTargets().remove(ct);
}
public Iterator allCopyTargets() {
return getCopyTargets().iterator();
}
public CopyTarget[] allCopyTargetsAsArray() {
if(allCopyTargetsSize() > 0)
return (CopyTarget[]) getCopyTargets().toArray(new CopyTarget[allCopyTargetsSize()]);
return new CopyTarget[0];
}
public int allCopyTargetsSize() {
return getCopyTargets().size();
}
public void setCopyTargets(List l) {
getPOJOCopyRun().setCopyTargets(l);
}
public List getCopyTargets() {
List l = getPOJOCopyRun().getCopyTargets();
if(!isInitialized(l)) {
initialize(l);
}
return l;
}
public int totalCopies() {
checkInitialized();
return getPOJOCopyRun().totalCopies();
}
public int totalCopyFailures() {
checkInitialized();
return getPOJOCopyRun().totalCopyFailures();
}
public int totalSizeKB() {
checkInitialized();
return getPOJOCopyRun().totalSizeKB();
}
public List allFailures() {
return getPOJOCopyRun().allFailures();
}
public void checkInitialized() {
List l = getPOJOCopyRun().getCopyTargets();
if(!isInitialized(l)) {
initialize(l);
}
}
protected void setStateStr(String str) {
setState(CopyRunState.getStateFor(str));
}
protected String getStateStr() {
return getState().getState();
}
protected void setRunStartDateLong(long l) {
Calendar c = Calendar.getInstance();
c.setTimeInMillis(l);
setRunStartDate(c);
}
protected long getRunStartDateLong() {
Calendar c = getRunStartDate();
if(c != null)
return c.getTimeInMillis();
else
return -1;
}
protected void setRunEndDateLong(long l) {
Calendar c = Calendar.getInstance();
c.setTimeInMillis(l);
setRunEndDate(c);
}
protected long getRunEndDateLong() {
Calendar c = getRunEndDate();
if(c != null)
return c.getTimeInMillis();
else
return -1;
}
private POJOCopyRun getPOJOCopyRun() {
if(pojoCopyRun == null)
pojoCopyRun = new POJOCopyRun();
return pojoCopyRun;
}
private POJOCopyRun pojoCopyRun;
}
HIBCopyTarget
-------------------------------------------------------------------------------------
public class HIBCopyTarget extends HIBDBObj implements CopyTarget {
public Object getPOJO() {
return getPOJOCopyTarget();
}
public void setURL(String url) {
getPOJOCopyTarget().setURL(url);
}
public String getURL() {
return getPOJOCopyTarget().getURL();
}
public void addCopySpec(CopySpec cs) {
getCopySpecs().add(cs);
}
public void removeCopySpec(CopySpec cs) {
getCopySpecs().remove(cs);
}
public Iterator allCopySpecs() {
return getCopySpecs().iterator();
}
public CopySpec[] allCopySpecsAsArray() {
if(allCopySpecsSize() > 0)
return (CopySpec[]) getCopySpecs().toArray(new CopySpec[allCopySpecsSize()]);
return new CopySpec[0];
}
public int allCopySpecsSize() {
return getCopySpecs().size();
}
public void setCopySpecs(List l) {
getPOJOCopyTarget().setCopySpecs(l);
}
public List getCopySpecs() {
List l = getPOJOCopyTarget().getCopySpecs();
if(!isInitialized(l)) {
initialize(l);
}
return l;
}
public int totalCopies() {
checkInitialized();
return getPOJOCopyTarget().totalCopies();
}
public int totalCopyFailures() {
checkInitialized();
return getPOJOCopyTarget().totalCopyFailures();
}
public int totalSizeKB() {
checkInitialized();
return getPOJOCopyTarget().totalSizeKB();
}
public List allFailures() {
return getPOJOCopyTarget().allFailures();
}
public POJOCopyTarget getPOJOCopyTarget() {
if(pojoCopyTarget == null)
pojoCopyTarget = new POJOCopyTarget();
return pojoCopyTarget;
}
public void setParentCopyRun(CopyRun cr) {
parentCopyRun = cr;
}
public CopyRun getParentCopyRun() {
return parentCopyRun;
}
public void checkInitialized() {
List l = getPOJOCopyTarget().getCopySpecs();
if(!isInitialized(l)) {
initialize(l);
}
}
private POJOCopyTarget pojoCopyTarget;
private CopyRun parentCopyRun;
}
POJOCopyJob
--------------------------------------------------------------------------------
public class POJOCopyJob extends POJOBObj implements CopyJob {
public void cascadePostUpdate() {
Iterator it = getCopyRuns().iterator();
while(it.hasNext())
((CopyRun) it.next()).onPostUpdate();
}
public void cascadePostSave() {
Iterator it = getCopyRuns().iterator();
while(it.hasNext())
((CopyRun) it.next()).onPostSave();
}
public boolean isPOJO() {
return true;
}
public void setName(String name) {
this.name = name;
changed();
}
public String getName() {
return this.name;
}
public void addCopyRun(CopyRun cr) {
getCopyRuns().add(cr);
changed();
}
public void removeCopyRun(CopyRun cr) {
getCopyRuns().remove(cr);
changed();
}
public Iterator allCopyRuns() {
return getCopyRuns().iterator();
}
public CopyRun[] allCopyRunsAsArray() {
return (CopyRun[]) getCopyRuns().toArray(new CopyRun[getCopyRuns().size()]);
}
public int allCopyRunsSize() {
return getCopyRuns().size();
}
public void setCopyRuns(List l) {
copyRuns = l;
}
public List getCopyRuns() {
if(copyRuns == null)
copyRuns = new ArrayList();
return copyRuns;
}
public int totalCopies() {
int copies = 0;
Iterator it = allCopyRuns();
while(it.hasNext()) {
CopyRun cr = (CopyRun) it.next();
copies = copies + cr.totalCopies();
}
return copies;
}
public int totalCopyFailures() {
int copies = 0;
Iterator it = allCopyRuns();
while(it.hasNext()) {
CopyRun cr = (CopyRun) it.next();
copies = copies + cr.totalCopyFailures();
}
return copies;
}
public int totalSizeKB() {
int size = 0;
Iterator it = allCopyRuns();
while(it.hasNext()) {
CopyRun cr = (CopyRun) it.next();
size = size + cr.totalSizeKB();
}
return size;
}
public List allFailures() {
List l = new ArrayList();
Iterator it = allCopyRuns();
while(it.hasNext()) {
CopyRun cr = (CopyRun) it.next();
l.add(cr.allFailures());
}
return l;
}
private String name;
private List copyRuns;
}
POJOCopyRun
---------------------------------------------------------------------------------
public class POJOCopyRun extends POJOBObj implements CopyRun {
public void cascadePostUpdate() {
Iterator it = getCopyTargets().iterator();
while(it.hasNext())
((CopyTarget) it.next()).onPostUpdate();
}
public void cascadePostSave() {
Iterator it = getCopyTargets().iterator();
while(it.hasNext())
((CopyTarget) it.next()).onPostSave();
}
public boolean isPOJO() {
return true;
}
public void setName(String name) {
this.name = name;
changed();
}
public String getName() {
return name;
}
public void setState(CopyRunState crs) {
state = crs;
changed();
}
public CopyRunState getState() {
return state;
}
public void setParentCopyJob(CopyJob cj) {
parent = cj;
changed();
}
public CopyJob getParentCopyJob() {
return parent;
}
public void setRunStartDate(Calendar c) {
runStartDate = c;
changed();
}
public Calendar getRunStartDate() {
return runStartDate;
}
public void setRunEndDate(Calendar c) {
runEndDate = c;
changed();
}
public Calendar getRunEndDate() {
return runEndDate;
}
public void addCopyTarget(CopyTarget ct) {
getCopyTargets().add(ct);
changed();
}
public void removeCopyTarget(CopyTarget ct) {
getCopyTargets().remove(ct);
changed();
}
public Iterator allCopyTargets() {
return getCopyTargets().iterator();
}
public CopyTarget[] allCopyTargetsAsArray() {
return (CopyTarget[]) getCopyTargets().toArray(new CopyTarget[getCopyTargets().size()]);
}
public int allCopyTargetsSize() {
return getCopyTargets().size();
}
public void setCopyTargets(List l) {
copyTargets = l;
changed();
}
public List getCopyTargets() {
if(copyTargets == null)
copyTargets = new ArrayList();
return copyTargets;
}
public int totalCopies() {
int total = 0;
Iterator it = allCopyTargets();
while(it.hasNext()) {
CopyTarget ct = (CopyTarget) it.next();
total = total + ct.totalCopies();
}
return total;
}
public int totalCopyFailures() {
int failures = 0;
Iterator it = allCopyTargets();
while(it.hasNext()) {
CopyTarget ct = (CopyTarget) it.next();
failures = failures + ct.totalCopyFailures();
}
return failures;
}
public int totalSizeKB() {
int size = 0;
Iterator it = allCopyTargets();
while(it.hasNext()) {
CopyTarget ct = (CopyTarget) it.next();
size = size + ct.totalSizeKB();
}
return size;
}
public List allFailures() {
List l = new ArrayList();
Iterator it = allCopyTargets();
while(it.hasNext()) {
CopyTarget ct = (CopyTarget) it.next();
l.add(ct.allFailures());
}
return l;
}
private String name;
private CopyRunState state = CopyRunState.NOT_STARTED;
private CopyJob parent;
private Calendar runStartDate;
private Calendar runEndDate;
private List copyTargets;
}
POJOCopyTarget
-------------------------------------------------------------------------------------
public class POJOCopyTarget extends POJOBObj implements CopyTarget {
public void cascadePostUpdate() {
Iterator it = getCopySpecs().iterator();
while(it.hasNext())
((CopySpec) it.next()).onPostUpdate();
}
public void cascadePostSave() {
Iterator it = getCopySpecs().iterator();
while(it.hasNext())
((CopySpec) it.next()).onPostSave();
}
public boolean isPOJO() {
return true;
}
public void setURL(String url) {
this.url = url;
changed();
}
public String getURL() {
return url;
}
public void addCopySpec(CopySpec cs) {
getCopySpecs().add(cs);
changed();
}
public void removeCopySpec(CopySpec cs) {
getCopySpecs().remove(cs);
changed();
}
public Iterator allCopySpecs() {
return getCopySpecs().iterator();
}
public CopySpec[] allCopySpecsAsArray() {
return (CopySpec[]) getCopySpecs().toArray(new CopySpec[getCopySpecs().size()]);
}
public int allCopySpecsSize() {
return getCopySpecs().size();
}
public void setCopySpecs(List l) {
copySpecs = l;
changed();
}
public List getCopySpecs() {
if(copySpecs == null)
copySpecs = new ArrayList();
return copySpecs;
}
public int totalCopies() {
int total = 0;
Iterator it = allCopySpecs();
while(it.hasNext()) {
CopySpec cs = (CopySpec) it.next();
if(cs.didCopy())
total++;
}
return total;
}
public int totalCopyFailures() {
int failures = 0;
Iterator it = allCopySpecs();
while(it.hasNext()) {
CopySpec cs = (CopySpec) it.next();
if(!cs.didCopy())
failures++;
}
return failures;
}
public int totalSizeKB() {
int size = 0;
Iterator it = allCopySpecs();
while(it.hasNext()) {
CopySpec cs = (CopySpec) it.next();
if(cs.didCopy())
size = size + cs.getSizeInKB();
}
return size;
}
public List allFailures() {
List l = new ArrayList();
Iterator it = allCopySpecs();
while(it.hasNext()) {
CopySpec cs = (CopySpec) it.next();
if(!cs.didCopy())
l.add(cs);
}
return l;
}
private String url;
private List copySpecs;
}
Full stack trace of any exception that occurs:
10:08:50,726 ERROR PersistentCollection:206 - Failed to lazily initialize a collection
net.sf.hibernate.HibernateException: Session is currently disconnected
at net.sf.hibernate.impl.SessionImpl.connection(SessionImpl.java:3143)
at net.sf.hibernate.impl.BatcherImpl.prepareQueryStatement(BatcherImpl.java:61)
at net.sf.hibernate.loader.Loader.prepareQueryStatement(Loader.java:703)
at net.sf.hibernate.loader.Loader.doQuery(Loader.java:184)
at net.sf.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:132)
at net.sf.hibernate.loader.Loader.loadCollection(Loader.java:909)
at net.sf.hibernate.loader.Loader.loadCollection(Loader.java:884)
at net.sf.hibernate.loader.OneToManyLoader.initialize(OneToManyLoader.java:80)
at net.sf.hibernate.collection.AbstractCollectionPersister.initialize(AbstractCollectionPersister.java:284)
at net.sf.hibernate.impl.SessionImpl.initializeCollection(SessionImpl.java:3133)
at net.sf.hibernate.collection.PersistentCollection.initialize(PersistentCollection.java:203)
at net.sf.hibernate.collection.PersistentCollection.read(PersistentCollection.java:69)
at net.sf.hibernate.collection.Bag.iterator(Bag.java:255)
at com.gsk.legal.copy.bo.pojo.POJOCopyTarget.allCopySpecs(POJOCopyTarget.java:54)
at com.gsk.legal.copy.bo.pojo.POJOCopyTarget.totalCopies(POJOCopyTarget.java:78)
at com.gsk.legal.copy.bo.himpl.HIBCopyTarget.totalCopies(HIBCopyTarget.java:68)
at com.gsk.legal.copy.bo.pojo.POJOCopyRun.totalCopies(POJOCopyRun.java:120)
at com.gsk.legal.copy.bo.himpl.HIBCopyRun.totalCopies(HIBCopyRun.java:102)
at com.gsk.legal.copy.bo.pojo.POJOCopyJob.totalCopies(POJOCopyJob.java:78)
at com.gsk.legal.copy.bo.himpl.HIBCopyJob.totalCopies(HIBCopyJob.java:74)
at com.gsk.legal.copy.plugin.ct.views.CopyStatsView.setData(CopyStatsView.java:58)
at com.gsk.legal.copy.plugin.ct.views.CopyJobDetailsView.setData(CopyJobDetailsView.java:62)
at com.gsk.legal.copy.plugin.ct.views.CopyJobDetailsView.selectionChanged(CopyJobDetailsView.java:69)
Name and version of the database you are using:
Oracle 9i
The generated SQL (show_sql=true):
Debug level Hibernate log excerpt:
|