Double persist of Entity field with Cascade.ALL

#1

I am building a JavaEE application using Netbeans 7.0.1, Glassfish 3.1 and ObjectDB 2.3.3.

I have a Book class with entity field Chapter which has a CascadeType.ALL property. The Book fields are as follows:

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String bookTitle;
@OneToMany(cascade= CascadeType.ALL, fetch= FetchType.EAGER)
private List<Chapter> chapters;

The Chapter fields are as follows:

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String chapterTitle;

The idea is that after I make changes to the Book class on the client side (i.e. by adding or removing new Chapters), merging the Book class on the server side should result in new and modified Chapters being persisted and merged accordingly.

This works as expected on the Book table, however with side effect on the Chapter table. For every new Chapter added to the Book, there are two Chapter records (usually added in sequential id) on the Chapter table when viewed in Explorer.

Let me also mention an additional observation I made: if the new chapters are created and added to the Book entity ON THE SERVER SIDE, then the Chapter table is OK (no duplicate records).

I have attached all the classes involved in the error case. I would like to know if there is a way I can make the error case scenario work as that would result in much easier development for me.
Thanks.

#2

The following are modified for the working case where new Chapters are added ON THE SERVER SIDE. 

#3

To demonstrate the problem please submit a simple test case as explained in the posting instructions.

If this is not possible (for example because the problem happens only in a Java EE application) - at lease submit a complete runnable Eclipse / NetBeans project as one zip file + exact instructions how to run it.

ObjectDB Support
#4

Attached is the complete Netbeans project with the error case. It contains

1. App client (Book_dberror_client),

2. The enterprise application (Book_dberror) which contains the EJB module (Book_dberror-ejb)

3. A Java Class Library (Book_dberror_Libs).

In Netbeans, I added the Java EE 6 API Library from Netbeans to Book_dberror_Libs and Objectdb.jar to Book_dberror_ejb.

In persistence.xml, I had to use ObjectDB server because Netbeans kept deleting my database each time I deployed with stand-alone mode. You can un-comment the property for stand-alone mode in the persistence.xml to use it.

I created the application using Netbeans 7.0.1, Glassfish 3.1 and ObjectDB 2.3.3

To run the application:

  1. Unzip the attachments to the same location, 
  2. Open Book_dberror project in Netbeans (this should also open all required projects)
  3. Run Book_dberror enterprise app project.
  4. On the Netbeans output console, when prompted first enter:     1 + enter    to persist a Book record to database.
  5. Run Book_dberror enterprise app project again.
  6. On the Netbeans output console, when prompted enter:     2 + enter    to add a Chapter to the book record.

In ObjectDB Explorer, you should see the Book table correctly recorded but the Chapter table would have double entry of same record.

#5

For completeness, attached is the modified sample that moves all Entity manipulation code to the Server in Netbeans project. This works flawlessly, however it might result in more complicated code for some use-cases.

Running it is same as above, only replace:

  1. Book_dberror_client with Book_db_client
  2. Book_dberror with Book_db
  3. Book_dberror-ejb with Book_db-ejb
  4. Book_dberror_Libs with Book_db_Libs

Thanks.

#6

Your test project demonstrates a bug in cascading merge to new entity objects.

A new issue was filled. Hopefully it will be fixed soon. Thank you for this report.

ObjectDB Support

Reply