persistence@glassfish.java.net

Re: find does not return updated entity

From: Mitesh Meswani <mitesh.meswani_at_oracle.com>
Date: Mon, 20 Dec 2010 13:56:40 -0800

This should clarify what is happening
http://weblogs.java.net/blog/guruwons/archive/2006/09/understanding_t_1.html

On 12/20/2010 1:47 PM, reljicb wrote:
> Dear all,
>
> I have a problem understanding entityManager.find(...) function.
> According to the documentation, as well as the book "Pro JPA 2 - Mastering
> the Java™ Persistence API" (Mike Keith, Merrick Schincariol), the method
> should attempt to return the entity from the Persistence Context, if it is
> managed, or from the underlying DB, if not.
>
> Well, that doesn't happen to me when I rollback the active transaction, and
> than start it again. Although the transaction rolled back, and the
> Persistence Context should be cleared, when I start a new transaction (and
> get supposingly a fresh new Persistence Context), find() returns me the old
> state of the entity which I changed externally between two transactions.
>
> To simplify the problem I created a test JPA-based application (java 6,
> netbeans 6.9, toplink, mysql) with the following code:
>
> public static void main(String[] args) {
> ...
> em.getTransaction().begin();
>
> Node test = em.find(Node.class, 14303);
> System.out.println("node id:14303 name:" + test.getIdName());
>
> if (args.length> 0) {
> String nodeName = args[0];
>
> test = em.find(Node.class, 14303);
> test.setName(nodeName);
> System.out.println("node renamed to:" + test.getIdName());
> test = null;
>
> em.flush();
> em.getTransaction().commit();
> System.out.println("transaction commited");
> } else {
> em.getTransaction().rollback();
> System.out.println("transaction rollback");
> System.out.println("node id:14303 is managed:" + em.contains(test));
> test = null;
>
> try {
> System.out.println("waiting 7 sec -----");
> Thread.sleep(10000);
> System.out.println("wake up -----");
> } catch (InterruptedException ex) {
> System.out.println(ex);
> }
> }
> em.getTransaction().begin();
> System.out.println("transaction begin");
>
> test = em.find(Node.class, 14303);
> System.out.println("node id:14303 name:" + test.getIdName());
> System.out.println("node id:14303 is managed:" + em.contains(test));
>
> em.getTransaction().rollback();
> ...
> }
>
>
> Node entity:
>
> @Entity
> @Table(name = "node")
> public class Node implements Serializable {
> ...
> @Id
> @GeneratedValue(strategy = GenerationType.IDENTITY)
> @Basic(optional = false)
> @Column(name = "id")
> private Integer id;
>
> @Basic(optional = false)
> @Column(name = "name")
> private String name;
>
> public Node() {
> }
>
>
> public String getName() {
> return name;
> }
>
> public void setName(String name) {
> this.name = name;
> }
> public String getIdName() {
> return getName() + " (id:" + this.getId() + ")";
> }
> public Integer getId() {
> return id;
> }
>
> public void setId(Integer id) {
> this.id = id;
> }
> ...
> }
>
> I run main application from two command lines.
> From the first command line window I run the app WITHOUT command line
> arguments.
> So, it does not change entity, but only read its state twice, in two
> transactions, with break of 10sec between rollback of the first trans and
> begin of the second.
>
> While the first process is in waiting mode for 10sec, I run the second
> process with command line arguments (for example: "test1"), which changes
> the entity quickly. This process finishes within 10 secs of the pause of the
> first process.
>
> Now, when the first process comes out of the pause, I expect it to see the
> change done by the second process.
> However, this does not happen. Can anybody figure out why?
>
> Here's the output I get:
>
> first process (entity changing):
> node id:14303 name:test123 (id:14303)
> transaction rollback
> node id:14303 is managed:false
> waiting 7 sec -----
> wake up -----
> transaction begin
> node id:14303 name:test123 (id:14303)
> node id:14303 is managed:true
>
> second process (read-only):
>
> node id:14303 name:test123 (id:14303)
> node renamed to:test1 (id:14303)
> transaction commited
> transaction begin
> node id:14303 name:test1 (id:14303)
> node id:14303 is managed:true
>
>
> Thanks a lot for all help in advance.
>
> Best,
> Bojan
>