dev@glassfish.java.net

Re: Is my code buggy?

From: Markus KARG <markus.karg_at_gmx.net>
Date: Fri, 04 Jan 2008 09:44:34 +0100

Marina,

thank you for your kind answer.
> The JPA spec in the section 9.1.9 GeneratedValue Annotation says about
> various strategies: "This specification does not define the exact
> behavior of these strategies.". It might be a known bug in TopLink,
> but we always advised to call em.flush() if somebody needed to get a
> hold of the generated PK.
You are absolutely right, I was just blind that day. ;-)

In particular, I found the following in JPA 1.0 specification chapter
"3.2.1 Persisting an Entity Instance":

"A new entity instance becomes both managed and persistent by invoking
the persist method on it or by cascading the persist operation. The
semantics of the persist operation, applied to an entity X are as
follows: • If X is a new entity, it becomes managed. The entity X will
be entered into the database at or before transaction commit or as a
result of the flush operation."

Okay, that says it all: A user MUST invoke flush() or commit() to make
the O/R mapper talk to the database server, so it is NOT a bug, neither
of TopLink in general, nor of the particular part of TopLink that I
wrote. That completely and unambigously answers my question. Once more
it was helpful to ask before filing a bug report. :-)

For all people scanning the mailing list for a solution to the same
problem, here is the corrected code that works pretty well:

em.getTransaction().begin();
Article a1 = new Article();
em.persist(a1);
em.flush(); // <--- FLUSH (OR COMMIT) IS NEEDED HERE
System.out.println(a1.getId()); // Prints: 60 // Prints: 0 WITHOUT
flush() or commit()
Article a2 = em.find(Article.class, 60);
System.out.println(a2.getId()); // Prints: 60
em.getTransaction().commit();

Maybe someone likes to add this snippet tho the user's FAQ. :-)

Thanks for pointing me in the right direction!

Have Fun
Markus
>
> Regards,
> -marina
>
> Markus KARG wrote:
>> Hi all,
>>
>> as you know, I am the author of the Sybase support in TopLink
>> Essentials. :-)
>>
>> I just tried a short code snipped and noticed a strange behaviour.
>> Since I do not know whether that is wanted by JPA spec, or a bug of
>> TopLink, or a bug of my own code, I want to discuss with you prior to
>> filing a bug report.
>>
>> See the following code snippet:
>>
>> em.getTransaction().begin();
>> Article a1 = new Article();
>> em.persist(a1);
>> System.out.println(a1.getId()); // Prints: 0
>> Article a2 = em.find(Article.class, 60);
>> System.out.println(a2.getId()); // Prints: 60
>> em.getTransaction().commit();
>>
>> "Article" is an entity that is using IDENTITY strategy for generating
>> its primary key:
>>
>> @Id
>> @GeneratedValue(strategy = GenerationType.IDENTITY)
>> private int id;
>>
>> The database wrapper used, obviously, is the one I wrote. ;-)
>>
>> As you can see, when asking for the generated ID directly after
>> em.persist(a1), it returns the wrong value of 0. In fact, it
>> certainly shall tell the actually generated value of 60, since it is
>> impossible to know that value -- and such it is impossible to ask for
>> that PK explicitely as I have done it in the em.find() line. But
>> knowing the PK might be critical to some use cases. In fact, my
>> Sybase wrapper included in TopLink so far has code that reads back
>> the created value -- but it seems that value gets lost "somewhere". I
>> know that somebody changed my code recently to support IDENTITY and
>> SEQUENCE strategy at the same time. Maybe he broke it?
>>
>> So my question is: IS THAT A BUG?
>>
>> And if it is: Is that a bug of my Sybase wrapper, or a bug of TopLink?
>>
>> Thanks
>> Markus
>>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe_at_glassfish.dev.java.net
> For additional commands, e-mail: dev-help_at_glassfish.dev.java.net
>


-- 
http://www.xing.com/go/invita/58469