Eager fetching missing an element when retrieved remotely no
bigdaddy May 26, 2008 3:59 PMI am not sure if this forum is where this problem should be posted, but here it goes.
Using:
Java: 1.5.0_15; Java HotSpot(TM) Client VM 1.5.0_15-b04
JBoss AS: 4.2.2.GA
I am trying to implement eager fetching with a parent-to-child (many-to-many) and child-to-grandchild (many-to-many) relationship setup. After all entities are created and I retrieve the grandchildren with EAGER fetching, I am able to iterate through the list of grandchildren and view the grandchildren with it's related children and the children's related parents BEFORE leaving the JBoss server to return the results to a remote client. AFTER leaving the server and the remote client receives the results I iterate through the same grandchildren and see that the parent does not contain the same children as was present before the data left the server. If you run the files I have provided you will notice output from the server log console does not match output from the remote client. It is as if the returned information is being cut off. The child sizes for parentId=402881821a263a42011a26a349aa00ab are different (JBossAS = 2 and remote client = 1) in this sample output. The output from the server side is what is expected.
Sample output
JBossAS console:
...
15:10:15,296 INFO [ParentChildGrandchildWorkerBean]
-------------------------------------------------------------------------
15:10:15,296 INFO [ParentChildGrandchildWorkerBean] Parent[test.ejb3.ParentTbl[
parentId=402881821a263a42011a26a3498b00aa]] has child size = 3 -- [test.ejb3.Chi
ldTbl[childId=402881821a263a42011a26a349d900ac], test.ejb3.ChildTbl[childId=4028
81821a263a42011a26a34a2700ae], test.ejb3.ChildTbl[childId=402881821a263a42011a26
a34a0800ad]]
15:10:15,296 INFO [ParentChildGrandchildWorkerBean] Parent[test.ejb3.ParentTbl[
parentId=402881821a263a42011a26a349aa00ab]] has child size = 2 -- [test.ejb3.Chi
ldTbl[childId=402881821a263a42011a26a349d900ac], test.ejb3.ChildTbl[childId=4028
81821a263a42011a26a34a2700ae]]
15:10:15,296 INFO [ParentChildGrandchildWorkerBean]
DONE=========================================================================DON
E
Remote client:
...
-------------------------------------------------------------------------
Parent[test.ejb3.ParentTbl[parentId=402881821a263a42011a26a349aa00ab]] has child size = 1 -- [test.ejb3.ChildTbl[childId=402881821a263a42011a26a349d900ac]]
Parent[test.ejb3.ParentTbl[parentId=402881821a263a42011a26a3498b00aa]] has child size = 3 -- [test.ejb3.ChildTbl[childId=402881821a263a42011a26a34a0800ad], test.ejb3.ChildTbl[childId=402881821a263a42011a26a34a2700ae], test.ejb3.ChildTbl[childId=402881821a263a42011a26a349d900ac]]
DONE=========================================================================DONE
I do not know if there is something wrong with Java, JBoss remoting, EJB3, etc. Hopefully, someone will be able to point out something I may have overlooked or something that I may have misunderstood.
Here are the files:
persistence.xml
<?xml version="1.0" encoding="UTF-8"?> <persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"> <persistence-unit name="test-parent-child-grandchildPU" transaction-type="JTA"> <provider>org.hibernate.ejb.HibernatePersistence</provider> <jta-data-source>java:/testerejb3db</jta-data-source> <properties> <property name="hibernate.hbm2ddl.auto" value="create-drop"/> </properties> </persistence-unit> </persistence>
ParentChildGrandchildWorkerBean.java
package test.ejb3.workers; import java.util.Date; import java.util.Iterator; import java.util.List; import java.util.Vector; import javax.ejb.Stateless; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import javax.persistence.Query; import org.apache.log4j.Logger; import test.ejb3.entity.ChildTbl; import test.ejb3.entity.GrandchildTbl; import test.ejb3.entity.ParentTbl; import test.ejb3.localinterfaces.ParentChildGrandchildWorkerLocal; import test.ejb3.remoteinterfaces.ParentChildGrandchildWorkerRemote; @Stateless public class ParentChildGrandchildWorkerBean implements ParentChildGrandchildWorkerLocal, ParentChildGrandchildWorkerRemote { private static final long serialVersionUID = 1L; private static Logger logger = Logger.getLogger(ParentChildGrandchildWorkerBean.class); @PersistenceContext private EntityManager entityManager; public ParentTbl addParent(ParentTbl parentTbl) { return entityManager.merge(parentTbl); } public ParentTbl findParent(String parentId) { return entityManager.find(ParentTbl.class, parentId); } public Vector<ParentTbl> findUnassignedParents() { Vector<ParentTbl> resultList; Query query; query = entityManager.createNamedQuery("ParentTbl.findUnassigned"); resultList = new Vector<ParentTbl>(query.getResultList()); return resultList; } public ChildTbl addChild(ChildTbl childTbl) { return entityManager.merge(childTbl); } public ChildTbl findChild(String childId) { return entityManager.find(ChildTbl.class, childId); } public Vector<ChildTbl> findUnassignedChildren() { Vector<ChildTbl> resultList; Query query; query = entityManager.createNamedQuery("ChildTbl.findUnassigned"); resultList = new Vector<ChildTbl>(query.getResultList()); return resultList; } public GrandchildTbl addGrandchild(GrandchildTbl grandchildTbl) { return entityManager.merge(grandchildTbl); } public GrandchildTbl findGrandchild(String grandchildId) { return entityManager.find(GrandchildTbl.class, grandchildId); } public GrandchildTbl findGrandchild(Date startDate, Date endDate) { Vector<GrandchildTbl> gtList; GrandchildTbl result = null; gtList = findGrandchild(startDate, endDate, true); if (! gtList.isEmpty()) { result = gtList.get(0); } return result; } public Vector<GrandchildTbl> findGrandchildren(Date startDate, Date endDate) { return findGrandchild(startDate, endDate, false); } public void removeAll() { List<ParentTbl> parentTbls; List<ChildTbl> childTbls; List<GrandchildTbl> grandchildTbls; Query query; query = entityManager.createNamedQuery("ParentTbl.findAll"); parentTbls = query.getResultList(); for (Iterator<ParentTbl> i = parentTbls.iterator(); i.hasNext();) { entityManager.remove(i.next()); i.remove(); } query = entityManager.createNamedQuery("ChildTbl.findAll"); childTbls = query.getResultList(); for (Iterator<ChildTbl> i = childTbls.iterator(); i.hasNext();) { entityManager.remove(i.next()); i.remove(); } query = entityManager.createNamedQuery("GrandchildTbl.findAll"); grandchildTbls = query.getResultList(); for (Iterator<GrandchildTbl> i = grandchildTbls.iterator(); i.hasNext();) { entityManager.remove(i.next()); i.remove(); } } private Vector<GrandchildTbl> findGrandchild(Date startDate, Date endDate, boolean useExactDate) { Vector<GrandchildTbl> resultList; Query query; entityManager.flush(); query = useExactDate ? entityManager.createNamedQuery("GrandchildTbl.findByExactDate") : entityManager.createNamedQuery("GrandchildTbl.findByDates"); query.setParameter("startDate", startDate); query.setParameter("endDate", endDate); resultList = new Vector<GrandchildTbl>(query.getResultList()); for (GrandchildTbl gt : resultList) { logger.info("\n#########################################################################"); for (ChildTbl ct : gt.getChildTblCollection()) { logger.info("\n========================================================================="); logger.info("Child[" + ct + "] has grand child size = " + ct.getGrandChildTblCollection().size()); logger.info("Child[" + ct + "] has parent size = " + ct.getParentTblCollection().size()); logger.info("\n-------------------------------------------------------------------------"); for (ParentTbl pt : ct.getParentTblCollection()) { logger.info("Parent[" + pt + "] has child size = " + pt.getChildTblCollection().size() + " -- " + pt.getChildTblCollection()); } } } logger.info("\nDONE=========================================================================DONE\n"); return resultList; } public Vector<GrandchildTbl> findUnassignedGrandchildren() { Vector<GrandchildTbl> resultList; Query query; query = entityManager.createNamedQuery("GrandchildTbl.findUnassigned"); resultList = new Vector<GrandchildTbl>(query.getResultList()); return resultList; } public void addChildToParent(ParentTbl parentTbl, ChildTbl childTbl) { ParentTbl pt; ChildTbl ct; pt = findParent(parentTbl.getParentId()); ct = findChild(childTbl.getChildId()); pt.getChildTblCollection().add(ct); ct.getParentTblCollection().add(pt); } public void addGrandchildToChild(ChildTbl childTbl, GrandchildTbl grandchildTbl) { ChildTbl ct; GrandchildTbl gt; ct = findChild(childTbl.getChildId()); gt = findGrandchild(grandchildTbl.getGrandchildId()); ct.getGrandChildTblCollection().add(gt); gt.getChildTblCollection().add(ct); } }
ParentChildGrandchildWorker.java
package test.ejb3.commoninterfaces; import java.util.Date; import java.util.Vector; import test.ejb3.entity.ChildTbl; import test.ejb3.entity.GrandchildTbl; import test.ejb3.entity.ParentTbl; public interface ParentChildGrandchildWorker { public void removeAll(); public ParentTbl addParent(ParentTbl parentTbl); public ParentTbl findParent(String parentId); public Vector<ParentTbl> findUnassignedParents(); public ChildTbl addChild(ChildTbl childTbl); public ChildTbl findChild(String childId); public GrandchildTbl addGrandchild(GrandchildTbl grandchildTbl); public GrandchildTbl findGrandchild(String grandchildId); public Vector<ChildTbl> findUnassignedChildren(); /** * Get all grandchildren between provided dates. * * @param startDate * @param endDate */ public Vector<GrandchildTbl> findGrandchildren(Date startDate, Date endDate); public GrandchildTbl findGrandchild(Date startDate, Date endDate); public Vector<GrandchildTbl> findUnassignedGrandchildren(); public void addChildToParent(ParentTbl parentTbl, ChildTbl childTbl); public void addGrandchildToChild(ChildTbl childTbl, GrandchildTbl grandchildTbl); }
ParentChildGrandchildWorkerRemote.java
package test.ejb3.remoteinterfaces; import javax.ejb.Remote; import test.ejb3.commoninterfaces.ParentChildGrandchildWorker; @Remote public interface ParentChildGrandchildWorkerRemote extends ParentChildGrandchildWorker { }
ParentChildGrandchildWorkerLocal.java
package test.ejb3.localinterfaces; import javax.ejb.Local; import test.ejb3.commoninterfaces.ParentChildGrandchildWorker; @Local public interface ParentChildGrandchildWorkerLocal extends ParentChildGrandchildWorker { }
GrandchildTbl.java
package test.ejb3.entity; import java.io.Serializable; import java.util.Date; import java.util.Set; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.JoinTable; import javax.persistence.ManyToMany; import javax.persistence.NamedQueries; import javax.persistence.NamedQuery; import javax.persistence.Table; import javax.persistence.Temporal; import javax.persistence.TemporalType; @Entity @Table(name = "grandchildtbl") @NamedQueries({@NamedQuery(name = "GrandchildTbl.findAll", query = "SELECT g FROM GrandchildTbl g"), @NamedQuery(name = "GrandchildTbl.findByExactDate", query = "SELECT g FROM GrandchildTbl g WHERE g.startDate = :startDate AND " + "g.endDate = :endDate"), @NamedQuery(name = "GrandchildTbl.findByDates", query = "SELECT g FROM GrandchildTbl g WHERE g.startDate >= :startDate AND " + "g.endDate <= :endDate"), @NamedQuery(name = "GrandchildTbl.findUnassigned", query = "SELECT DISTINCT g FROM GrandchildTbl g WHERE g.childTblCollection IS EMPTY")}) public class GrandchildTbl implements Serializable { private static final long serialVersionUID = 1L; @Id @GeneratedValue(generator = "system-uuid") @Column(name = "grandchild_id", nullable = false) private String grandchildId; @Column(name = "notes") private String notes; @Column(name = "start_date", nullable = false) @Temporal(TemporalType.TIMESTAMP) private Date startDate; @Column(name = "end_date", nullable = false) @Temporal(TemporalType.TIMESTAMP) private Date endDate; @JoinTable(name = "childgrandchild", joinColumns = {@JoinColumn(name = "grandchild_id", referencedColumnName = "grandchild_id")}, inverseJoinColumns = {@JoinColumn(name = "child_id", referencedColumnName = "child_id")}) @ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER) private Set<ChildTbl> childTblCollection; public GrandchildTbl() { } public GrandchildTbl(String grandchildId) { this.grandchildId = grandchildId; } public String getGrandchildId() { return grandchildId; } public void setGrandchildId(String grandchildId) { this.grandchildId = grandchildId; } public String getNotes() { return notes; } public void setNotes(String notes) { this.notes = notes; } public Date getStartDate() { return startDate; } public void setStartDate(Date startDate) { this.startDate = startDate; } public Date getEndDate() { return endDate; } public void setEndDate(Date endDate) { this.endDate = endDate; } public Set<ChildTbl> getChildTblCollection() { return childTblCollection; } public void setChildTblCollection(Set<ChildTbl> childTblCollection) { this.childTblCollection = childTblCollection; } @Override public int hashCode() { int hash = 0; hash += (grandchildId != null ? grandchildId.hashCode() : 0); return hash; } @Override public boolean equals(Object object) { // TODO: Warning - this method won't work in the case the id fields are not set if (!(object instanceof GrandchildTbl)) { return false; } GrandchildTbl other = (GrandchildTbl) object; if ((this.grandchildId == null && other.grandchildId != null) || (this.grandchildId != null && !this.grandchildId.equals(other.grandchildId))) { return false; } return true; } @Override public String toString() { return "test.ejb3.GrandchildTbl[grandchildId=" + grandchildId + "]"; } }
ChildTbl.java
package test.ejb3.entity; import java.io.Serializable; import java.util.Set; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.JoinTable; import javax.persistence.ManyToMany; import javax.persistence.NamedQueries; import javax.persistence.NamedQuery; import javax.persistence.Table; @Entity @Table(name = "childtbl") @NamedQueries({@NamedQuery(name = "ChildTbl.findAll", query = "SELECT c FROM ChildTbl c"), @NamedQuery(name = "ChildTbl.findUnassigned", query = "SELECT DISTINCT c FROM ChildTbl c " + "WHERE c.grandchildTblCollection IS EMPTY AND " + "c.parentTblCollection IS EMPTY")}) public class ChildTbl implements Serializable { private static final long serialVersionUID = 1L; @Id @GeneratedValue(generator = "system-uuid") @Column(name = "child_id", nullable = false) private String childId; @Column(name = "notes") private String notes; @JoinTable(name = "parentchild", joinColumns = {@JoinColumn(name = "child_id", referencedColumnName = "child_id")}, inverseJoinColumns = {@JoinColumn(name = "parent_id", referencedColumnName = "parent_id")}) @ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER) private Set<ParentTbl> parentTblCollection; @ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER, mappedBy = "childTblCollection") private Set<GrandchildTbl> grandchildTblCollection; public ChildTbl() { } public ChildTbl(String childId) { this.childId = childId; } public String getChildId() { return childId; } public void setChildId(String childId) { this.childId = childId; } public String getNotes() { return notes; } public void setNotes(String notes) { this.notes = notes; } public Set<ParentTbl> getParentTblCollection() { return parentTblCollection; } public void setParentTblCollection(Set<ParentTbl> parentTblCollection) { this.parentTblCollection = parentTblCollection; } public Set<GrandchildTbl> getGrandChildTblCollection() { return grandchildTblCollection; } public void setGrandChildTblCollection(Set<GrandchildTbl> grandchildTblCollection) { this.grandchildTblCollection = grandchildTblCollection; } @Override public int hashCode() { int hash = 0; hash += (childId != null ? childId.hashCode() : 0); return hash; } @Override public boolean equals(Object object) { // TODO: Warning - this method won't work in the case the id fields are not set if (!(object instanceof ChildTbl)) { return false; } ChildTbl other = (ChildTbl) object; if ((this.childId == null && other.childId != null) || (this.childId != null && !this.childId.equals(other.childId))) { return false; } return true; } @Override public String toString() { return "test.ejb3.ChildTbl[childId=" + childId + "]"; } }
ParentTbl.java
package test.ejb3.entity; import java.io.Serializable; import java.util.Set; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.ManyToMany; import javax.persistence.NamedQueries; import javax.persistence.NamedQuery; import javax.persistence.Table; @Entity @Table(name = "parenttbl") @NamedQueries({@NamedQuery(name = "ParentTbl.findAll", query = "SELECT p FROM ParentTbl p"), @NamedQuery(name = "ParentTbl.findUnassigned", query = "SELECT DISTINCT p FROM ParentTbl p WHERE p.childTblCollection IS EMPTY")}) public class ParentTbl implements Serializable { private static final long serialVersionUID = 1L; @Id @GeneratedValue(generator = "system-uuid") @Column(name = "parent_id", nullable = false) private String parentId; @Column(name = "notes") private String notes; @ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER, mappedBy = "parentTblCollection") private Set<ChildTbl> childTblCollection; public ParentTbl() { } public ParentTbl(String parentId) { this.parentId = parentId; } public String getParentId() { return parentId; } public void setParentId(String parentId) { this.parentId = parentId; } public String getNotes() { return notes; } public void setNotes(String notes) { this.notes = notes; } public Set<ChildTbl> getChildTblCollection() { return childTblCollection; } public void setChildTblCollection(Set<ChildTbl> childTblCollection) { this.childTblCollection = childTblCollection; } @Override public int hashCode() { int hash = 0; hash += (parentId != null ? parentId.hashCode() : 0); return hash; } @Override public boolean equals(Object object) { // TODO: Warning - this method won't work in the case the id fields are not set if (!(object instanceof ParentTbl)) { return false; } ParentTbl other = (ParentTbl) object; if ((this.parentId == null && other.parentId != null) || (this.parentId != null && !this.parentId.equals(other.parentId))) { return false; } return true; } @Override public String toString() { return "test.ejb3.ParentTbl[parentId=" + parentId + "]"; } }
package-info.java
@GenericGenerator(name="system-uuid", strategy="uuid") package test.ejb3.entity; import org.hibernate.annotations.GenericGenerator;
TestParentChildGrandchild.java <---- remote client
package testclientejb3; import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; import java.util.Vector; import java.util.logging.Level; import java.util.logging.Logger; import javax.naming.Context; import javax.naming.InitialContext; import javax.naming.NamingException; import javax.rmi.PortableRemoteObject; import test.ejb3.entity.ChildTbl; import test.ejb3.entity.GrandchildTbl; import test.ejb3.entity.ParentTbl; import test.ejb3.remoteinterfaces.ParentChildGrandchildWorkerRemote; public class TestParentChildGrandchild { private enum ContextScheme { JNP, HTTP; } private java.util.Hashtable <java.lang.String, java.lang.String> environment; private void initEnvironment(ContextScheme contextScheme, String providerHost, String providerPort) { String url = contextScheme.toString().toLowerCase() + "://" + providerHost + ":" + providerPort; String initialContextFactory = "org.jnp.interfaces.NamingContextFactory"; if (contextScheme.equals(ContextScheme.HTTP)) { url = url + "/invoker/JNDIFactory"; initialContextFactory = "org.jboss.naming.HttpNamingContextFactory"; } environment = new java.util.Hashtable<java.lang.String, java.lang.String>(); environment.put(javax.naming.Context.INITIAL_CONTEXT_FACTORY, initialContextFactory); environment.put(javax.naming.Context.PROVIDER_URL, url); environment.put(javax.naming.Context.URL_PKG_PREFIXES, "org.jboss.naming:org.jnp.interfaces"); } public ParentTbl getParent(int parentNumber) { ParentTbl parentTbl; parentTbl = new ParentTbl(); parentTbl.setNotes("Hello world - parent " + parentNumber + "."); return parentTbl; } public ChildTbl getChild(int childNumber) { ChildTbl childTbl; childTbl = new ChildTbl(); childTbl.setNotes("Hello world - child " + childNumber + "."); return childTbl; } public GrandchildTbl getGrandchildTbl(int grandchildNumber) { GrandchildTbl grandchildTbl; Date date = new Date(); grandchildTbl = new GrandchildTbl(); grandchildTbl.setNotes("Hello world - grand child " + grandchildNumber + "."); grandchildTbl.setStartDate(date); grandchildTbl.setEndDate(date); return grandchildTbl; } public void test() { Context initialContext; Vector<ParentTbl> parentVector; Vector<ChildTbl> childVector; Vector<GrandchildTbl> grandchildVector; GregorianCalendar gregorianCalendar; ParentTbl firstParentTbl; ParentTbl lastParentTbl; ChildTbl childTbl; GrandchildTbl grandchildTbl; int numOfParents = 2; int numOfChildren = 3; int numOfGrandchildren = 8; try { initEnvironment(ContextScheme.JNP, "localhost", "1099"); initialContext = new InitialContext(environment); Object ref = initialContext.lookup("ParentChildGrandchildWorkerBean/remote"); ParentChildGrandchildWorkerRemote parentChildGrandchildWorkerRemote = (ParentChildGrandchildWorkerRemote) PortableRemoteObject.narrow(ref, ParentChildGrandchildWorkerRemote.class); parentChildGrandchildWorkerRemote.removeAll(); // Create parents, children, and grandchildren for (int i = 0; i < numOfParents; i++) { parentChildGrandchildWorkerRemote.addParent(getParent(i)); } for (int i = 0; i < numOfChildren; i++) { parentChildGrandchildWorkerRemote.addChild(getChild(i)); } for (int i = 0; i < numOfGrandchildren; i++) { parentChildGrandchildWorkerRemote.addGrandchild(getGrandchildTbl(i)); } parentVector = parentChildGrandchildWorkerRemote.findUnassignedParents(); childVector = parentChildGrandchildWorkerRemote.findUnassignedChildren(); grandchildVector = parentChildGrandchildWorkerRemote.findUnassignedGrandchildren(); firstParentTbl = parentVector.get(0); lastParentTbl = parentVector.get(numOfParents - 1); // Add 1st grandchild to 1st child // Add 1st child to 1st and last parent childTbl = childVector.get(0); grandchildTbl = grandchildVector.get(0); parentChildGrandchildWorkerRemote.addGrandchildToChild(childTbl, grandchildTbl); parentChildGrandchildWorkerRemote.addChildToParent(firstParentTbl, childTbl); parentChildGrandchildWorkerRemote.addChildToParent(lastParentTbl, childTbl); // Add middle grandchildren to middle child // Add middle child to 1st parent childTbl = childVector.get(1); for (int i = 1; i < numOfGrandchildren - 1; i++) { grandchildTbl = grandchildVector.get(i); parentChildGrandchildWorkerRemote.addGrandchildToChild(childTbl, grandchildTbl); } parentChildGrandchildWorkerRemote.addChildToParent(firstParentTbl, childTbl); // Add last grandchild to last child // Add last child to 1st and last parent childTbl = childVector.get(numOfChildren - 1); grandchildTbl = grandchildVector.get(numOfGrandchildren - 1); parentChildGrandchildWorkerRemote.addGrandchildToChild(childTbl, grandchildTbl); parentChildGrandchildWorkerRemote.addChildToParent(firstParentTbl, childTbl); parentChildGrandchildWorkerRemote.addChildToParent(lastParentTbl, childTbl); gregorianCalendar = new GregorianCalendar(); gregorianCalendar.clear(); gregorianCalendar.set(Calendar.YEAR, 1600); System.out.println("searching from " + gregorianCalendar.getTime()); // Get all grandchildren with eager fetching grandchildVector = parentChildGrandchildWorkerRemote.findGrandchildren(gregorianCalendar.getTime(), new Date()); System.out.println("grandchildVector = " + grandchildVector); for (GrandchildTbl gt : grandchildVector) { System.out.println("\n#########################################################################"); for (ChildTbl ct : gt.getChildTblCollection()) { System.out.println("\n========================================================================="); System.out.println("Child[" + ct + "] has grand child size = " + ct.getGrandChildTblCollection().size()); System.out.println("Child[" + ct + "] has parent size = " + ct.getParentTblCollection().size()); System.out.println("\n-------------------------------------------------------------------------"); for (ParentTbl pt : ct.getParentTblCollection()) { System.out.println("Parent[" + pt + "] has child size = " + pt.getChildTblCollection().size() + " -- " + pt.getChildTblCollection()); } } } System.out.println("\nDONE=========================================================================DONE\n"); } catch (NamingException ex) { Logger.getLogger(TestParentChildGrandchild.class.getName()).log(Level.SEVERE, null, ex); } } /** * @param args the command line arguments */ public static void main(String[] args) { TestParentChildGrandchild test = new TestParentChildGrandchild(); test.test(); } }