You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@openjpa.apache.org by Christian Defoy <ch...@gmail.com> on 2007/07/25 20:56:13 UTC
OpenJPA is not inserting the parent reference on update
Hello,
For some reason, I am unable to update an object that is already
persisted. Here's how it goes:
I have a Shape object that includes an Attachment. This is already
saved in the database. I update the Shape by replacing its Attachment
object with a new one that contains a Note object:
manager.getTransaction().begin();
Shape loadedBase = manager.find( Shape.class, 18 );
// Create new attachment
Attachment newAttach = new Attachment();
newAttach.setValue( "attachment 2" );
Note note = new Note();
note.setText( "note text" );
note.setParent( newAttach );
newAttach.setNote( note );
newAttach.setParent( loadedBase );
loadedBase.setAttachment( newAttach );
manager.getTransaction().commit();
Upon commiting this transaction, I see the following statements:
INSERT INTO NOTE (NOTE_TEXT) VALUES (?) [params=(String) note text]
INSERT INTO ATTACH (SHAPE_ID, VALUE) VALUES (?, ?) [params=(int) 12,
(String) attachment 2]
CALL IDENTITY()
DELETE FROM ATTACH WHERE ATTACH_ID = ? [params=(int) 44]
UPDATE NOTE SET PARENT_ID = ? WHERE NOTE_ID = ? [params=(int) 45, (int) 0]
The first statement in the list throws an exception as Note must
provide a parent:
Attempt to insert null into a non-nullable column: column: PARENT_ID
table: NOTE in statement [INSERT INTO NOTE (NOTE_TEXT) VALUES (?)]
{prepstmnt 11544872 INSERT INTO NOTE (NOTE_TEXT) VALUES (?)
[params=(String) note text]} [code=-10, state=23000]
What am I doing wrong?
I am able to get the transaction to commit properly by either
- setting PROPERTY access on the Note object;
- detaching the Shape object before updating it and calling merge();
- starting my transaction once my new Attachment object is created and
Note object is set;
- stepping inside the code using Eclipse.
In all cases, the Attachment object is inserted first and then the
Note object is inserted with a reference to the Attachment.
Thanks in advance!
Christian
-----
@Entity
@Table(name="SHAPE")
public class Shape
{
@Column(name="shape_id")
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private int id;
private String name;
@OneToOne( mappedBy="parent", cascade=CascadeType.ALL,
fetch=FetchType.EAGER )
@Dependent
private Attachment attachment;
// Getters and setters are trivial
}
@Entity
@Table( name="attach" )
public class Attachment
{
@Id
@GeneratedValue( strategy=GenerationType.IDENTITY )
@Column( name="attach_id" )
private int id;
@OneToOne( cascade=CascadeType.ALL, fetch=FetchType.LAZY )
@Column( name="shape_id" )
private Shape parent;
private String value;
@OneToOne( mappedBy="parent", cascade=CascadeType.ALL )
private Note note;
// Getters and setters are trivial
}
@Entity
@Table( name="note" )
public class Note
{
@Id
@GeneratedValue( strategy=GenerationType.IDENTITY )
@Column( name="note_id" )
private int id;
@OneToOne( optional=false )
@Column( name="parent_id" )
private Attachment parent;
@Column( name="note_text", length=20 )
private String text;
// Getters and setters are trivial
}
Re: OpenJPA is not inserting the parent reference on update
Posted by Christian Defoy <ch...@gmail.com>.
Hi!
I managed to get around the problem by invoking manager.remove() on my
Attachment object before replacing it with the one. It seems to work
so far...
Prior to that, I was almost successfull by detaching my Shape object
prior to replacing its Attachment object. But then, when the
Attachment object was deleted (marked with @Dependent), it sometimes
came before the Note objects and since there is a cascade delete in
the db, an exception was thrown for optimistic lock failure...
Christian
Re: OpenJPA is not inserting the parent reference on update
Posted by Christian Defoy <ch...@gmail.com>.
Hi Patrick,
I am using Hypersonic verswion 1.8.0.4.
Here is the 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"
version="1.0">
<persistence-unit name="basic" transaction-type="RESOURCE_LOCAL">
<class>ex3.Shape</class>
<class>ex3.Attachment</class>
<class>ex3.Note</class>
<properties>
<property name="openjpa.Log" value="DefaultLevel=INFO, SQL=TRACE"/>
<property name="openjpa.ConnectionRetainMode" value="always"/>
<property name="openjpa.ConnectionUserName" value="sa"/>
<property name="openjpa.ConnectionPassword" value=""/>
<property name="openjpa.ConnectionURL"
value="jdbc:hsqldb:hsql://localhost/jpa-db"/>
<property name="openjpa.ConnectionDriverName"
value="org.hsqldb.jdbcDriver"/>
<property name="openjpa.FetchBatchSize" value="-1" />
<property name="openjpa.jdbc.SchemaFactory"
value="native(ForeignKeys=true)" />
</properties>
</persistence-unit>
</persistence>
Hope this sheds some light on the problem!
Christian
On 7/25/07, Patrick Linskey <pl...@gmail.com> wrote:
> Hi,
>
> It sounds like a foreign key ordering problem. What db are you using?
> Can you post your persistence.xml properties?
>
> -Patrick
>
> On 7/25/07, Christian Defoy <ch...@gmail.com> wrote:
> > Hello,
> >
> > For some reason, I am unable to update an object that is already
> > persisted. Here's how it goes:
> >
> > I have a Shape object that includes an Attachment. This is already
> > saved in the database. I update the Shape by replacing its Attachment
> > object with a new one that contains a Note object:
> >
> > manager.getTransaction().begin();
> > Shape loadedBase = manager.find( Shape.class, 18 );
> >
> > // Create new attachment
> > Attachment newAttach = new Attachment();
> > newAttach.setValue( "attachment 2" );
> > Note note = new Note();
> > note.setText( "note text" );
> > note.setParent( newAttach );
> > newAttach.setNote( note );
> >
> > newAttach.setParent( loadedBase );
> > loadedBase.setAttachment( newAttach );
> > manager.getTransaction().commit();
> >
> > Upon commiting this transaction, I see the following statements:
> >
> > INSERT INTO NOTE (NOTE_TEXT) VALUES (?) [params=(String) note text]
> > INSERT INTO ATTACH (SHAPE_ID, VALUE) VALUES (?, ?) [params=(int) 12,
> > (String) attachment 2]
> > CALL IDENTITY()
> > DELETE FROM ATTACH WHERE ATTACH_ID = ? [params=(int) 44]
> > UPDATE NOTE SET PARENT_ID = ? WHERE NOTE_ID = ? [params=(int) 45, (int) 0]
> >
> > The first statement in the list throws an exception as Note must
> > provide a parent:
> >
> > Attempt to insert null into a non-nullable column: column: PARENT_ID
> > table: NOTE in statement [INSERT INTO NOTE (NOTE_TEXT) VALUES (?)]
> > {prepstmnt 11544872 INSERT INTO NOTE (NOTE_TEXT) VALUES (?)
> > [params=(String) note text]} [code=-10, state=23000]
> >
> > What am I doing wrong?
> >
> > I am able to get the transaction to commit properly by either
> > - setting PROPERTY access on the Note object;
> > - detaching the Shape object before updating it and calling merge();
> > - starting my transaction once my new Attachment object is created and
> > Note object is set;
> > - stepping inside the code using Eclipse.
> >
> > In all cases, the Attachment object is inserted first and then the
> > Note object is inserted with a reference to the Attachment.
> >
> > Thanks in advance!
> >
> > Christian
> >
> > -----
> >
> > @Entity
> > @Table(name="SHAPE")
> > public class Shape
> > {
> > @Column(name="shape_id")
> > @Id
> > @GeneratedValue(strategy=GenerationType.IDENTITY)
> > private int id;
> >
> > private String name;
> >
> > @OneToOne( mappedBy="parent", cascade=CascadeType.ALL,
> > fetch=FetchType.EAGER )
> > @Dependent
> > private Attachment attachment;
> >
> > // Getters and setters are trivial
> > }
> >
> > @Entity
> > @Table( name="attach" )
> > public class Attachment
> > {
> > @Id
> > @GeneratedValue( strategy=GenerationType.IDENTITY )
> > @Column( name="attach_id" )
> > private int id;
> >
> > @OneToOne( cascade=CascadeType.ALL, fetch=FetchType.LAZY )
> > @Column( name="shape_id" )
> > private Shape parent;
> >
> > private String value;
> >
> > @OneToOne( mappedBy="parent", cascade=CascadeType.ALL )
> > private Note note;
> >
> > // Getters and setters are trivial
> > }
> >
> > @Entity
> > @Table( name="note" )
> > public class Note
> > {
> > @Id
> > @GeneratedValue( strategy=GenerationType.IDENTITY )
> > @Column( name="note_id" )
> > private int id;
> >
> > @OneToOne( optional=false )
> > @Column( name="parent_id" )
> > private Attachment parent;
> >
> > @Column( name="note_text", length=20 )
> > private String text;
> >
> > // Getters and setters are trivial
> > }
> >
>
>
> --
> Patrick Linskey
> 202 669 5907
>
Re: OpenJPA is not inserting the parent reference on update
Posted by Patrick Linskey <pl...@gmail.com>.
Hi,
It sounds like a foreign key ordering problem. What db are you using?
Can you post your persistence.xml properties?
-Patrick
On 7/25/07, Christian Defoy <ch...@gmail.com> wrote:
> Hello,
>
> For some reason, I am unable to update an object that is already
> persisted. Here's how it goes:
>
> I have a Shape object that includes an Attachment. This is already
> saved in the database. I update the Shape by replacing its Attachment
> object with a new one that contains a Note object:
>
> manager.getTransaction().begin();
> Shape loadedBase = manager.find( Shape.class, 18 );
>
> // Create new attachment
> Attachment newAttach = new Attachment();
> newAttach.setValue( "attachment 2" );
> Note note = new Note();
> note.setText( "note text" );
> note.setParent( newAttach );
> newAttach.setNote( note );
>
> newAttach.setParent( loadedBase );
> loadedBase.setAttachment( newAttach );
> manager.getTransaction().commit();
>
> Upon commiting this transaction, I see the following statements:
>
> INSERT INTO NOTE (NOTE_TEXT) VALUES (?) [params=(String) note text]
> INSERT INTO ATTACH (SHAPE_ID, VALUE) VALUES (?, ?) [params=(int) 12,
> (String) attachment 2]
> CALL IDENTITY()
> DELETE FROM ATTACH WHERE ATTACH_ID = ? [params=(int) 44]
> UPDATE NOTE SET PARENT_ID = ? WHERE NOTE_ID = ? [params=(int) 45, (int) 0]
>
> The first statement in the list throws an exception as Note must
> provide a parent:
>
> Attempt to insert null into a non-nullable column: column: PARENT_ID
> table: NOTE in statement [INSERT INTO NOTE (NOTE_TEXT) VALUES (?)]
> {prepstmnt 11544872 INSERT INTO NOTE (NOTE_TEXT) VALUES (?)
> [params=(String) note text]} [code=-10, state=23000]
>
> What am I doing wrong?
>
> I am able to get the transaction to commit properly by either
> - setting PROPERTY access on the Note object;
> - detaching the Shape object before updating it and calling merge();
> - starting my transaction once my new Attachment object is created and
> Note object is set;
> - stepping inside the code using Eclipse.
>
> In all cases, the Attachment object is inserted first and then the
> Note object is inserted with a reference to the Attachment.
>
> Thanks in advance!
>
> Christian
>
> -----
>
> @Entity
> @Table(name="SHAPE")
> public class Shape
> {
> @Column(name="shape_id")
> @Id
> @GeneratedValue(strategy=GenerationType.IDENTITY)
> private int id;
>
> private String name;
>
> @OneToOne( mappedBy="parent", cascade=CascadeType.ALL,
> fetch=FetchType.EAGER )
> @Dependent
> private Attachment attachment;
>
> // Getters and setters are trivial
> }
>
> @Entity
> @Table( name="attach" )
> public class Attachment
> {
> @Id
> @GeneratedValue( strategy=GenerationType.IDENTITY )
> @Column( name="attach_id" )
> private int id;
>
> @OneToOne( cascade=CascadeType.ALL, fetch=FetchType.LAZY )
> @Column( name="shape_id" )
> private Shape parent;
>
> private String value;
>
> @OneToOne( mappedBy="parent", cascade=CascadeType.ALL )
> private Note note;
>
> // Getters and setters are trivial
> }
>
> @Entity
> @Table( name="note" )
> public class Note
> {
> @Id
> @GeneratedValue( strategy=GenerationType.IDENTITY )
> @Column( name="note_id" )
> private int id;
>
> @OneToOne( optional=false )
> @Column( name="parent_id" )
> private Attachment parent;
>
> @Column( name="note_text", length=20 )
> private String text;
>
> // Getters and setters are trivial
> }
>
--
Patrick Linskey
202 669 5907