openjpa-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Sandhya Turaga <turagasa...@yahoo.com>
Subject Re: Unexpected merge/cascade behavior
Date Mon, 05 Jan 2009 18:46:26 GMT
Hi Jonathan,

       Gimme a day or two to give you the patch or the work around to the problem. Because
of the holiday season I could not fix it until now.

Thanks
Sandhya Turaga

--- On Mon, 1/5/09, Jonatan Samoocha <jonatan.samoocha@ps.net> wrote:
From: Jonatan Samoocha <jonatan.samoocha@ps.net>
Subject: Re: Unexpected merge/cascade behavior
To: users@openjpa.apache.org
Date: Monday, January 5, 2009, 2:58 AM

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 <jonatan.samoocha@ps.net>
wrote:
> From: Jonatan Samoocha <jonatan.samoocha@ps.net>
> Subject: Unexpected merge/cascade behavior
> To: users@openjpa.apache.org
> 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.




      
Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message