Win a copy of Mesos in Action this week in the Cloud/Virtualizaton forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Getting the value of a database Identity column in JPA

 
Jehan Jaleel
Ranch Hand
Posts: 196
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,

If I have a column defined at the database as an Identity like so...



And I tell JPA that the DB will generate this value...



When I do a merge, how can I get the value for this column that the DB generated?

In this example, if I simply call getAdviceHeaderId on the object that merge returns would this object have the value?

I am using JPA 2.0

Thanks,
Jahan
 
Anurag Verma
Ranch Hand
Posts: 167
Hibernate Spring Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
if integration is properly done (ie you are able to save the object using Entity Manager), then whenever you will fetch the Object using JPA, then the getter of property will give you the auto-generated value.
 
James Sutherland
Ranch Hand
Posts: 553
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
IDENTITY generated values cannot be preallocated as they require the insert to occur. So, calling persist(), or merge() of a new object will not assign the Id until you call flush() or commit().

In general I would not recommend IDENTITY, use TABLE or SEQUENCE instead, then you can preallocate value and will have better performance.
 
Jehan Jaleel
Ranch Hand
Posts: 196
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
So James if I understand you correctly, right now I will need to flush or commit before I can get the value of the Identity column from the getter of the object. Whereas if I use a Sequence instead I can get the value from the getter before calling flush.

Thanks.
 
James Sutherland
Ranch Hand
Posts: 553
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Yes, if you use TABLE or SEQUENCE you can get the id after calling persist(), or merge().
 
Hemant Thard
Ranch Hand
Posts: 122
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,

Please correct me if I am wrong.

IDENTITY generated values cannot be preallocated as they require the insert to occur. So, calling persist(), or merge() of a new object will not assign the Id until you call flush() or commit().


When you are using IDENTITY Class generator, JPA issues a Insert statement and it will not wait for flush() or commit() call. The supporting facts for this behavior is if you do some modification on this object(now persist after calling persist() or merge() ), you will see an update query been fired at the time of session flushing rather than only one insert query fired at the time of flushing.


 
Jehan Jaleel
Ranch Hand
Posts: 196
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,

I tested this with both Identity and Sequence and neither seems to be working. In debug mode, I stepped over the line where entityManager.merge is called, then I looked in my object and the id field had not been set. I also did not see an Insert being fired or a nextval call to get the sequence from the DB. So are we sure this the way it is supposed to work or am I missing something?

Thanks.
 
Hemant Thard
Ranch Hand
Posts: 122
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,

Here is my observation when I tested with Identity generator class and hibernate.

1. when i call save() on new new Object, i saw an insert query fired and i was able to get primary key value from now persistent object.
2. When i call merge() on new Object, Insert query was fired, but i was getting null for my primary key.

It seems to be that if the object is transient, the way save() and merge behave is completely different.

I don't know the reason for this behavior, but can you try using persist() for new object and post your result.
 
Jehan Jaleel
Ranch Hand
Posts: 196
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Hemant,

I will try that. But I hope you know that in my case I am not using Hibernate to generate the identity, I am relying on the database. Have you tried it that way?

Thanks,
Jehan
 
Hemant Thard
Ranch Hand
Posts: 122
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
yes ..

but keep posting your test result.
 
Jehan Jaleel
Ranch Hand
Posts: 196
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hemant,

Yes you are right, when I called persist it did give me the value of the identity column.

However one thought I had, does this mean that if that JPA entity was part of a transaction then the txn is committed at that point?

Thanks.
 
Hemant Thard
Ranch Hand
Posts: 122
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Hi,

Answer to this depend upon the how you have implemented JPA in your application.

if you have one txn per session, i don't think that will be a problem.

but if you are using some pattern like session per conversation where a single session is spread across multiple request and any insert you do will have to be rollback by using delete query(manually) in case of Error.


 
Telemart Network
Greenhorn
Posts: 4
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Integration is must & should be done properly. JPA issues a Insert statement and it will not wait for flush() or commit() call. The supporting facts for this behavior is if you do some modification on this object. There can be conversions.
 
Hemant Thard
Ranch Hand
Posts: 122
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hemant Thard wrote:Hi,

Here is my observation when I tested with Identity generator class and hibernate.

1. when i call save() on new new Object, i saw an insert query fired and i was able to get primary key value from now persistent object.
2. When i call merge() on new Object, Insert query was fired, but i was getting null for my primary key.

It seems to be that if the object is transient, the way save() and merge behave is completely different.

I don't know the reason for this behavior, but can you try using persist() for new object and post your result.


Hi,

I think this observation is partially right.
Please take a look at this post that very well explains the difference between persist and merge.

 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic