File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
http://aspose.com/file-tools
The moose likes Object Relational Mapping and the fly likes 'new' operator vs updating database Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Databases » Object Relational Mapping
Bookmark " Watch " New topic
Author

'new' operator vs updating database

Ismael Upright
Ranch Hand

Joined: Feb 15, 2007
Posts: 166
Consider the following two entities:




Now, DAO for these classes:




And the problematic scenario:




Right now we have a shop and two books assigned to it in the database.
Now I want to replace an old book with new one:



After that I expect to have a bookShop in database as well as books: "Planets" and "Galaxies", and book "Stars" to be deleted.


The problem is that instead I have all three books in database: "Planets", "Stars" and "Galaxies".



My questions:

- Is there any annotation which detects such changes and makes them in database as well?

- ...or should I change my approach by preventing the use of new operator in such cases?

- Are there any good solutions (annotations or just patterns) for handling the removing and adding books to the shop in a way that will also update the database properly?
Paul Sturrock
Bartender

Joined: Apr 14, 2004
Posts: 10336

If your entity does not have an ID it is not an update. Rather than creating a new instance of Book, load the existing one and update it.


JavaRanch FAQ HowToAskQuestionsOnJavaRanch
Ralph Jaus
Ranch Hand

Joined: Apr 27, 2008
Posts: 342
Ismael Upright wrote:After that I expect to have a bookShop in database as well as books: "Planets" and "Galaxies", and book "Stars" to be deleted.
It's not possible with JPA (at least JPA 1) to delete entities in a one-to-many relationship from db through changing the list of related entities and merging. Deletion from db always requires some remove or delete command.

Ismael Upright wrote:book1 = new Book();
book1.name = "Galaxies";
book1.shop = bookShop;
dao.update(shop);
I actually wonder somewhat that this led to an insertion of a book. For, the entity shop is updated but the new entity that is referenced by book1 has never been added to shop's list of books.


SCJP 5 (98%) - SCBCD 5 (98%)
Ismael Upright
Ranch Hand

Joined: Feb 15, 2007
Posts: 166
Paul Sturrock wrote:If your entity does not have an ID it is not an update. Rather than creating a new instance of Book, load the existing one and update it.


My entities have IDs - hey are marked with @Id annotation.
Ismael Upright
Ranch Hand

Joined: Feb 15, 2007
Posts: 166
Ralph Jaus wrote:I actually wonder somewhat that this led to an insertion of a book. For, the entity shop is updated but the new entity that is referenced by book1 has never been added to shop's list of books.



It doesn't matter, the book still will be inserted. Notice that the shop's list of books have the reference of book1. Seems that JPA recognizes a change but instead of updating it inserts a new book.


I use JPA 2.0.



so... my further question is still:


Are there any good and nice patterns for handling the removing and adding books to the shop in a way that will also update the database properly?
Paul Sturrock
Bartender

Joined: Apr 14, 2004
Posts: 10336

Ismael Upright wrote:
Paul Sturrock wrote:If your entity does not have an ID it is not an update. Rather than creating a new instance of Book, load the existing one and update it.


My entities have IDs - hey are marked with @Id annotation.



Where in this code do you set the ID? The instance of Book associated with the instance of Shop has no identifier. You create a new instance of Book, and call merge. Merge will create a new instance in the database if it is not identified by anything. So if you had used the state of shop as is and updated the existing book you'd get the behaviour you want. Otherwise how else will Hibernate know to update an existing book, and which book to update?
Ismael Upright
Ranch Hand

Joined: Feb 15, 2007
Posts: 166
Paul Sturrock wrote:
Ismael Upright wrote:
Paul Sturrock wrote:If your entity does not have an ID it is not an update. Rather than creating a new instance of Book, load the existing one and update it.


My entities have IDs - hey are marked with @Id annotation.


Where in this code do you set the ID? The instance of Book associated with the instance of Shop has no identifier. You create a new instance of Book, and call merge. Merge will create a new instance in the database if it is not identified by anything. So if you had used the state of shop as is and updated the existing book you'd get the behaviour you want. Otherwise how else will Hibernate know to update an existing book, and which book to update?


Maybe we don't understand each other - if you mean the ID of the old book, you're right - it is not set in the new book object. But the new ID will be generated automatically thanks to annotation "@GeneratedValue".

And yes, now I see that Hibernate has no information that is the old book should be updated. "book1" is only the reference to the object.. thanks for pointing that out.


So... in the coding fewer it is quite easy to make this mistake and forget that the object is still in the database, even if you don't have the reference to it. Any good programming practices to solve that? Maybe disabling creation of new object using "new" operator or something?
Paul Sturrock
Bartender

Joined: Apr 14, 2004
Posts: 10336


So... in the coding fewer it is quite easy to make this mistake and forget that the object is still in the database, even if you don't have the reference to it.

How can your ORM know the object is intended to be an update without first identifying what it is updating? This is a fundamental of relational databases.


Any good programming practices to solve that? Maybe disabling creation of new object using "new" operator or something?


Not really, you just have to hope developers remember how the API works.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: 'new' operator vs updating database
 
Similar Threads
Searching row in database by a column which is not a primary key
"Removing a detached instance" exception while updating the entity
Is my approach right while inserting a foreign key?
Not-unique unique column
StaleStateException