Hi Sandhya,

I tried to run the test case on JPA2.0, but got the same result. Anyway, I
seem to be bound to JPA1.0.0 due to project constraints.

You mention "debugging the problem", does that mean the behavior displayed
in this test case is incorrect? How can I assist in debugging? Do you know
of any workaround?

Thanks,

Jonatan


Sandhya Kishore wrote:
> 
> Please ignore my previous email on this. I have reproduced the problem and
> I am trying to debug it. If I do not understand what is going on I will
> post the testcase.
> 
> --- On Wed, 12/17/08, Jonatan Samoocha <[email protected]> wrote:
> From: Jonatan Samoocha <[email protected]>
> Subject: Unexpected merge/cascade behavior
> To: [email protected]
> Date: Wednesday, December 17, 2008, 7:22 AM
> 
> Hi all,
> 
> I'm quite new to (Open)JPA and am experiencing unexpected behavior of the
> merge() operation. I'm dealing with a parent and child entity that are
> defined as follows:
> 
> //Parent:
> @Entity
> @Table(name="TEST_PARENT")
> public class TestParent {
>       @Id
>       @Column(name="ID", nullable=false)
>       private String id = new String();
>       
>       @Column(name="name")
>       private String name = new String();
>       
>       @OneToMany(mappedBy="parent", fetch=FetchType.EAGER, 
>                       cascade={CascadeType.ALL})
>       private Set<TestChild> children = new HashSet<TestChild>();
>       
>       @Override
>       public boolean equals(Object other) {
>               if (other != null && other instanceof TestParent) {
>                       return ((TestParent)other).getId().equals(this.id);
>               }
>               
>               return false;
>       }
> 
>       @Override
>       public int hashCode() {
>               return id.hashCode();
>       }
>         
>         // skipping getters/setters
>       
>         public void addChild(TestChild c) {
>               this.children.add(c);
>               c.setParent(this);
>       }
> }
> 
> //Child:
> @Entity
> @Table(name="TEST_CHILD")
> public class TestChild {
>       @Id
>       @Column(name="ID", nullable=false)
>       private String id = new String();
>       
>       @Column(name="NAME")
>       private String name = new String();
>       
>       @ManyToOne(cascade={CascadeType.ALL})
>       @JoinColumn(name="PARENT_ID", nullable=false)
>       private TestParent parent = new TestParent();
>       
>       @Override
>       public boolean equals(Object other) {
>               if (other != null && other instanceof TestChild) {
>                       return ((TestChild)other).getId().equals(this.id);
>               }
>               
>               return false;
>       }
> 
>       @Override
>       public int hashCode() {
>               return id.hashCode();
>       }
> 
>       //Skipping getters/setters
> }
> 
> 
> The class testing the merge() behavior looks as follows:
> public class PCTester {
>       private EntityManager em = null;
>       
>       public PCTester() {
>               EntityManagerFactory emf = 
> Persistence.createEntityManagerFactory(
>               "testFactory");
>               em = emf.createEntityManager();
>       }
>       
>       public void mergeParent(TestParent p) {
>               em.getTransaction().begin();
>               p = em.merge(p);
>               em.getTransaction().commit();
>       }
> 
>       public static void main(String[] args) {
>               TestParent p = new TestParent();
>               p.setId("1");
>               p.setName("parent-1-update");
>               
>               TestChild c = new TestChild();
>               c.setId("1");
>               c.setName("child-1-update");
>               
>               p.addChild(c);
>               
>               PCTester t = new PCTester();
>               t.mergeParent(p);
>       }
> }
> 
> Finally, the entity manager is configured as follows in persistence.xml:
> <persistence-unit name="testFactory">
>       
> <provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
>                
>               
> <class>com.lmco.jsf.alis.obphm.afrs.session.model.TestParent</class>
>               
> <class>com.lmco.jsf.alis.obphm.afrs.session.model.TestChild</class>
>               
>               <properties>
>                       <property name="openjpa.ConnectionURL"                  
>        
>                                   
> value="jdbc:oracle:thin:@PROPRIETARY"/>
>                       <property name="openjpa.ConnectionDriverName"
> value="oracle.jdbc.OracleDriver"/>
>                       <property name="openjpa.ConnectionUserName"
> value="PROPRIETARY"/>
>                       <property name="openjpa.ConnectionPassword"
> value="PROPRIETARY"/>
>                       <property name="openjpa.Log" value="SQL=TRACE"/>
>                       <property name="openjpa.ConnectionFactoryProperties" 
>                       value="PrettyPrint=true, PrettyPrintLineLength=72"/>
>               <property name="openjpa.jdbc.SchemaFactory"
>                               value="native(foreignKeys=true)" />
>               </properties>
>               
> </persistence-unit>
> 
> In case the database already contains parent and child records with id
> "1",
> the test runs without problems and both parent and child names are
> correctly
> updated. The SQL trace shows the following statements being executed:
> 
> SELECT t0.NAME, t1.PARENT_ID, t1.ID, t1.NAME 
>     FROM AFRS_USER.TEST_PARENT t0, AFRS_USER.TEST_CHILD t1 
>     WHERE t0.ID = ? AND t0.ID = t1.PARENT_ID(+) 
>     ORDER BY t1.PARENT_ID ASC
> [params=(String) 1]
> 
> UPDATE AFRS_USER.TEST_PARENT 
>     SET NAME = ? 
>     WHERE ID = ? 
> [params=(String) parent-1-update, (String) 1]
> 
> UPDATE AFRS_USER.TEST_CHILD 
>     SET PARENT_ID = ?, NAME = ? 
>     WHERE ID = ? 
> [params=(String) 1, (String) child-1-update, (String) 1]
> 
> 
> However, when parent and child do not exist in the database, the merge()
> operation throws an exception because the database tries to insert NULL
> into
> the parent table for reasons unknown to me:
> 
> SELECT t0.NAME, t1.PARENT_ID, t1.ID, t1.NAME 
>     FROM AFRS_USER.TEST_PARENT t0, AFRS_USER.TEST_CHILD t1 
>     WHERE t0.ID = ? AND t0.ID = t1.PARENT_ID(+) 
>     ORDER BY t1.PARENT_ID ASC 
> [params=(String) 1]
> 
> SELECT t0.NAME, t1.ID, t1.NAME 
>     FROM AFRS_USER.TEST_CHILD t0, AFRS_USER.TEST_PARENT t1 
>     WHERE t0.ID = ? AND t0.PARENT_ID = t1.ID(+) 
> [params=(String) 1]
> 
> // Unexpected!!
> SELECT t0.NAME, t1.PARENT_ID, t1.ID, t1.NAME 
>     FROM AFRS_USER.TEST_PARENT t0, AFRS_USER.TEST_CHILD t1 
>     WHERE t0.ID = ? AND t0.ID = t1.PARENT_ID(+) 
>     ORDER BY t1.PARENT_ID ASC 
> [params=(String) ]
> 
> INSERT INTO AFRS_USER.TEST_PARENT (ID, NAME) 
>     VALUES (?, ?) 
> [params=(String) 1, (String) parent-1-update]
> 
> INSERT INTO AFRS_USER.TEST_CHILD (ID, PARENT_ID, NAME) 
>     VALUES (?, ?, ?) 
> [params=(String) 1, (String) 1, (String) child-1-update]
> 
> // Unexpected!!
> INSERT INTO AFRS_USER.TEST_PARENT (ID, NAME) 
>     VALUES (?, ?) 
> [params=(String) , (String) ]
> 
> Leading to
> 
> Exception in thread "main" <openjpa-1.0.0-r420667:568756 fatal
> store error>
> org.apache.openjpa.persistence.RollbackException: The transaction has been
> rolled back.  See the nested exceptions for details on the errors that
> occurred.
> Etc...
> 
> When creating a new parent only (i.e. without children) in the test
> method,
> it is correctly persisted into the database with the merge() operation, so
> it seems that something goes wrong with cascading the merge to the child
> object.
> 
> Does anyone know what's the reason for the unexpected SQL statements?
> 
> Any help is highly appreciated.
> 
> Thanks,
> 
> Jonatan Samoocha
> 
> Using:
> OpenJPA 1.0.0
> JDK 1.5.0_14
> Oracle 10G
> 
> -- 
> View this message in context:
> http://n2.nabble.com/Unexpected-merge-cascade-behavior-tp1668355p1668355.html
> Sent from the OpenJPA Users mailing list archive at Nabble.com.
> 
> 

-- 
View this message in context: 
http://n2.nabble.com/Unexpected-merge-cascade-behavior-tp1668355p2112406.html
Sent from the OpenJPA Users mailing list archive at Nabble.com.

Reply via email to