find does not return updated entity

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

find does not return updated entity

reljicb
This post was updated on .
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 (read-only):
        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 (entity changing):

        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
Reply | Threaded
Open this post in threaded view
|

Re: find does not return updated entity

reljicb
here's the damn thing that finally helped me:

in persistence.xml configure the following:
   <property name="toplink.cache.shared.default" value="false"/>