surinder-insonix / datanucleus-appengine

Automatically exported from code.google.com/p/datanucleus-appengine
0 stars 0 forks source link

(JPA) Query returns stale data #199

Closed GoogleCodeExporter closed 8 years ago

GoogleCodeExporter commented 8 years ago
I've got an entity <Container> than contains entities <Item>(s).
Here is my actions.
I start transaction then update entity then flush updates to database.
Then I get all entities of class Item(s) for a container which contains my
updated Item.
But the list of retrieved items contains Item that does not have my changes.

I'm using SDK 1.3.2

@Entity
public class Container implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Key key;

    @OneToMany(mappedBy = "container", fetch = FetchType.LAZY)
    private List<Item> items = new ArrayList<Item>();

    public void setKey(Key key) {
        this.key = key;
    }

    public Key getKey() {
        return key;
    }

    public void setItems(List<Item> items) {
        this.items = items;
    }

    public List<Item> getItems() {
        return items;
    }

}

@Entity
public class Item implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Key key;

    @ManyToOne(fetch = FetchType.LAZY)
    private Container container;

    @Column
    private String value;

    public void setKey(Key key) {
        this.key = key;
    }

    public Key getKey() {
        return key;
    }

    public void setContainer(Container container) {
        this.container = container;
    }

    public Container getContainer() {
        return container;
    }

    public void setValue(String value) {
        this.value = value;
    }

    public String getValue() {
        return value;
    }

    @Override
    public String toString() {
        return "Item [key=" + key + ", value=" + value + "]";
    }
}

@Service("TestLocalService")
public class LocalService {

    protected final Log logger = LogFactory.getLog(getClass());

    public Key createContainer() {
        em.getTransaction().begin();
        Container container = new Container();
        em.persist(container);
        em.flush();
        logger.fatal("new container" + container.getKey());
        em.getTransaction().commit();
        return container.getKey();
    }

    public Key generateItems(Key containerKey) {
            em.getTransaction().begin();
        Container container = em.find(Container.class, containerKey);
        Key key = null;
        for (int i = 0; i < 5; i++) {
            Item item = new Item();
            item.setContainer(container);
            item.setValue(Integer.toString(i));
            em.persist(item);
            em.flush();
            key = item.getKey();
            logger.fatal("new item" + item);
        }
        em.getTransaction().commit();
        return key;
    }

    public void changeItems(Key containerKey, Key itemKey) {
            em.getTransaction().begin();
        Container container = em.find(Container.class, containerKey);
        Item changedItem = em.find(Item.class, itemKey);
        changedItem.setValue("xxx"); 
        em.flush();
        logger.fatal("changed item: " + changedItem);
        for (Item item : container.getItems()) {
            logger.fatal("list item: " + item); //
<----------------------------------- PROBLEM HERE (Item contains a stale
value of the field <value>)
        }
        em.getTransaction().commit();
    }

    public static void testListSync(LocalService service) {
            // MAIN TEST 
        Key containerKey = service.createContainer();
        Key itemKey = service.generateItems(containerKey);
        service.changeItems(containerKey, itemKey);
    }
}

Original issue reported on code.google.com by firewor...@gmail.com on 29 Mar 2010 at 3:40

GoogleCodeExporter commented 8 years ago
Please see 
http://code.google.com/appengine/docs/java/datastore/transactions.html#Isolation
_and_Consistency

"Unlike with most databases, queries and gets inside a datastore transaction do 
not see the results of previous writes inside that transaction. Specifically, 
if an entity is modified or deleted within a transaction, a query or get 
returns the original version of the entity as of the beginning of the 
transaction, or nothing if the entity did not exist then."

Original comment by max.r...@gmail.com on 17 Mar 2011 at 8:15