-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 9 posts ] 
Author Message
 Post subject: Insert bug if a rollback occurs
PostPosted: Wed Apr 04, 2007 7:02 am 
Newbie

Joined: Thu Dec 14, 2006 11:17 am
Posts: 9
Hello,

there seems to be an insert bug (em.persist) in the current Hibernate version.
The entity's primary key is a Long value, auto generated.

Entity:
Code:
@Entity
@Table(uniqueConstraints = @UniqueConstraint(colmnNames = {name}))
public class MyClass {
  private Long id;
  private String name;

  @Id
  @GeneratedValue(strategy = GenerationType.AUTO)
  public Long getId() {
    return id;
  }
  ...
}


Now I want to insert two objects: The first's name property is set to "foo" and second's one also to "foo". Both objects are in a collection and inserted within one transaction.
Ok, the first insert succeeds and the second fails because of the unique constraint. The pretty wired thing is that the first object has an id set although it's not in the database.
A rollback occurs and I am definitely sure that the id in the first object must not be set!

cheers,
Kasperl


Top
 Profile  
 
 Post subject:
PostPosted: Wed Apr 04, 2007 7:16 am 
Expert
Expert

Joined: Thu Sep 04, 2003 8:23 am
Posts: 368
ids are gived in a distinct transaction to avoid duplicate values. When you try to insert the first object, the id is calculated and is "consumed" so nobody else can take it again.
Rollbacking or not your transaction don't change this

_________________
Seb
(Please don't forget to give credits if you found this answer useful :)


Top
 Profile  
 
 Post subject:
PostPosted: Wed Apr 04, 2007 7:21 am 
Newbie

Joined: Thu Dec 14, 2006 11:17 am
Posts: 9
I can't image that this is the desired behavior, I can't distinct if an object is inserted or not.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Apr 04, 2007 7:43 am 
Hibernate Team
Hibernate Team

Joined: Mon Aug 25, 2003 9:11 pm
Posts: 4592
Location: Switzerland
Why would you want to do that? Your application, or at least your current conversation with the current object graph, is dead after an exception. Restart your conversation.

_________________
JAVA PERSISTENCE WITH HIBERNATE
http://jpwh.org
Get the book, training, and consulting for your Hibernate team.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Apr 04, 2007 8:15 am 
Newbie

Joined: Thu Dec 14, 2006 11:17 am
Posts: 9
I can't re-create the "dead" objects after an exception occurs!
So why is the id set although the object is not inserted in the DB?


Top
 Profile  
 
 Post subject:
PostPosted: Wed Apr 04, 2007 8:22 am 
Hibernate Team
Hibernate Team

Joined: Mon Aug 25, 2003 9:11 pm
Posts: 4592
Location: Switzerland
Because that is the contract.

You can not re-use the object graph of a failed transaction. You have no guarantee in what state that graph might be. You don't know why the transaction failed. This is not a Hibernate issue. What you have is simply a broken application design.

In your case, you are supposed to do a UNIQUE constraint check _before_ you persist something. Validation of integrity rules does not work with your "let's throw stuff against the database and see what sticks" approach.

_________________
JAVA PERSISTENCE WITH HIBERNATE
http://jpwh.org
Get the book, training, and consulting for your Hibernate team.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Apr 04, 2007 8:34 am 
Newbie

Joined: Thu Dec 14, 2006 11:17 am
Posts: 9
Do I really need to check the constraints before the insert/update?

How to do that?


Top
 Profile  
 
 Post subject:
PostPosted: Wed Apr 04, 2007 9:09 am 
Hibernate Team
Hibernate Team

Joined: Mon Aug 25, 2003 9:11 pm
Posts: 4592
Location: Switzerland
By executing a query to check for duplicate values. Optionally obtaining a table lock on the target table so that nobody can insert between your check and your insert. Basically, like you would design any database application without Hibernate.

_________________
JAVA PERSISTENCE WITH HIBERNATE
http://jpwh.org
Get the book, training, and consulting for your Hibernate team.


Top
 Profile  
 
 Post subject: Re:
PostPosted: Tue Mar 23, 2010 3:56 pm 
Newbie

Joined: Tue Mar 23, 2010 2:56 pm
Posts: 4
christian wrote:
By executing a query to check for duplicate values. Optionally obtaining a table lock on the target table so that nobody can insert between your check and your insert. Basically, like you would design any database application without Hibernate.


What you call "optional" is really a required step. You cannot guaranty uniqueness without it for the reason you have wrote in that "optional" step - modifications (insertion, update or delete) by other concurrent transactions between check time and modification time by subject transaction. In addition subject transaction needs to hold on to that lock for the entire duration (until it ends with commit or rollback), so other transactions can see/not see inserted/deleted values for their check to work consistently.

Cheers,

- Vlad


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 9 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.