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
}

Reply via email to