persistence@glassfish.java.net

find does not return updated entity

From: reljicb <bojan.reljic_at_gmail.com>
Date: Mon, 20 Dec 2010 13:47:16 -0800 (PST)

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

-- 
View this message in context: http://old.nabble.com/find-does-not-return-updated-entity-tp30499871p30499871.html
Sent from the java.net - glassfish persistence mailing list archive at Nabble.com.