-
1. Re: onetomany relationship question
wolfgangknauf Jul 7, 2009 5:18 AM (in response to lpiccoli)Hi,
Q1: for each child, you have to do this:ParentBean parent = ...; ChildBean child1 = ...; ==> parent.getChilds().add (child1); child1.setParent(parent);
Otherwise, the relation will not be saved, but there will be no error message.
Q2: I don't know what is happening if you call "setChilds" before loading them, but I would expect strange side effects at least when the collection is under EntityManager control (inside a session bean method/transaction). So better manipulate the collection returned by "getChilds" and add/remove items. I will give this a try in the next few days and update my Wiki if I find a "No go".
Q3: Did you activate SQL query logging in your persistence.xml?<?xml version="1.0" encoding="UTF-8"?> <persistence 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" version="1.0"> <persistence-unit name=".."> ... <properties> ... ===> <property name="hibernate.show_sql" value="true"></property> </properties> </persistence-unit> </persistence>
But I am not sure how the childs are loaded. I will take a look at the JBoss console when I near a computer with JBoss ;-)
Best regards
Wolfgang -
2. Re: onetomany relationship question
lpiccoli Jul 7, 2009 7:36 AM (in response to lpiccoli)thanks for the rapid response wolfgang.
i added the SQL tracing but there is *no* SQL when calling parent.getChilds().
So if i have understood the 'onetoMany' relationship, it doesnt populated the 'many' unless it has been explicitly set using the parent.setChilds().
This seems an almost pointless relationship.
In order to get the list of childs from existing data (ie.reference data), one must use a join query likeem.query( 'from Child child where child.parent_id=:id')
I was hoping the above would be executed during the retrieval of the 'many'.
Q1. what exactly is the point of the 'onetoMany' if it is only useful if used when explicitly setting the collection on the 'one' side?
any help to clarify the above is most appreciated.
-lp -
3. Re: onetomany relationship question
wolfgangknauf Jul 7, 2009 9:12 AM (in response to lpiccoli)Hi,
actually, the "to many" side should be automatically populated when you access it. So, there is no need to perform entity manager queries.
Depending on the fetchType of the relationship, different things might happen:
If fetchType is "EAGER", then the children will be loaded when the parent is loaded. In this case, the EntityManager will fire some join statement against the database to load parent and childs with one query.
If fetchType is "LAZY", then the first call to "parent.getChilds()" will trigger the child collection loading. This will only work if the parent entity is under EntityManager control.
Hope this helps a bit.
Wolfgang -
4. Re: onetomany relationship question
lpiccoli Jul 8, 2009 12:07 AM (in response to lpiccoli)ok it seems that my test cases were erroneous.
i finally got the onetomany to fetch the 'many' by refreshing the entity. This then invoked the following queryhibernate: select childbean0_.ID as ID3_, childbean0_.parent_ID as parent2_3_ from ChildBean childbean0_ where childbean0_.parent_ID=?
my test code also shows that the relationship only needs to be set on the many side.@Test public void one2manyTestWithSettingManySide() { ParentBean parent = new ParentBean(); entityManager.persist(parent); long id = parent.getId(); ChildBean child1 = new ChildBean(); child1.setParent(parent); entityManager.persist(child1); ChildBean child2 = new ChildBean(); child2.setParent(parent); entityManager.persist(child2); Query query = entityManager.createQuery("from ChildBean child where parent.id=:id"); query.setParameter("id", id); List resultList = query.getResultList(); assertEquals( 2, resultList.size() ); //check refresh entityManager.refresh(parent); assertEquals( 2, parent.getChilds().size() ); ParentBean parentBean = entityManager.find(ParentBean.class, parent.getId()); assertEquals( 2, parentBean.getChilds().size() ); }
thanks for your help wolfgang.
-lp -
5. Re: onetomany relationship question
wolfgangknauf Jul 8, 2009 4:34 PM (in response to lpiccoli)Hi,
I played around with your sample a bit. I agree that it works if you first create and save the parent, then create the child, set the parent and persist the child.
But assume that you don't save the parent, but the child. Here is the code snippet:ParentBean parent = new ParentBean(); entityManager.persist(parent); ChildBean child1 = new ChildBean(); parent.getChilds().add(child1); //child1.setParent(parentNew); entityManager.persist(parent)
In this case, child and parent will be saved without error messages, but the relationship related database data is missing.
So, as a general guideline: always update both sides of the relationship, this will avoid a lot of problems ;-).
Best regards
Wolfgang