Objectify 4: Transactions, session cache and ancestor queries

407 views
Skip to first unread message

Moritz

unread,
Sep 24, 2012, 1:54:07 PM9/24/12
to objectify...@googlegroups.com
From the new documentation:

Starting a transaction creates a new Objectify instance with a fresh, empty session cache. Loads and saves will populate this new instance cache; because of this, entities modified will appear modified after being loaded again within the same transaction. Unlike the low-level API, the datastore will not appear "frozen in time", although transaction isolation is maintained.

Am I right that this is not true for ancestor queries? From what I see they do return the results based "frozen" state of the datastore before the transaction started... if yes, then maybe the documentation could be a bit more explicit about that.
Just for curiosity: why can't queries not work on the session cache?

Jeff Schnitzer

unread,
Sep 24, 2012, 2:09:52 PM9/24/12
to objectify...@googlegroups.com
Can you produce a test case that demonstrates this? It shouldn't
matter how the query is formulated. Entries in the session cache
supersede query results no matter what. In fact, the way this works
is that the query results get put into the session cache (without
overwrite) and the cache values are what get returned to the client.

If you see some other behavior, it's a bug. But I'm pretty sure there
are test cases covering this. Is it possible you are mixing up
Objectify instances in and out of transactions? Always use static
ofy(), don't hold on to Objectify references.

What do you mean by why can't queries work on the session cache?
Queries work on index data that lives in the datastore. As mentioned
above, queries in Objectify prefer to return entity data in the
session cache... but there always needs to be a request to the
datastore to know _which_ entities to return.

Jeff

Moritz Blume

unread,
Sep 24, 2012, 2:34:44 PM9/24/12
to objectify...@googlegroups.com
Ok here is a short example that demonstrates my question:

    @Test
    public void sessionCache() {
        ofy().transact(new VoidWork() {
            @Override
            public void vrun() {
                ofy().save().entity(new Bar("theId")).now();
                Key<Bar> key = Key.create(Bar.class, "theId");
                ofy().save()
                        .entities(new Foo(key, "one"), new Foo(key, "two"),
                                new Foo(key, "three")).now();
                List<Foo> foos = new ArrayList<Foo>(ofy().load()
                        .type(Foo.class).ancestor(key).list());
                assertTrue(foos.size() == 3);
            }
        });
    }


and Foo and Bar are defined here:

@Entity
class Foo {
    @Parent
    Key<Bar> parent;
    @Id
    Long id;
    public String content;

    public Foo() {
    }

    public Foo(Key<Bar> parent, String content) {
        this.parent = parent;
        this.content = content;
    }
}

@Entity
class Bar {
    @Id
    String id;

    public Bar() {
    }

    public Bar(String id) {
        this.id = id;
    }
}
--
www.fasterplan.com | Meet Your Friends!

Moritz

unread,
Sep 28, 2012, 3:52:05 AM9/28/12
to objectify...@googlegroups.com, je...@infohazard.org
Hi Jeff,

thanks for clarifying this. If I understand you correctly, if I save a new entity within a transaction any further query in the same transaction won't return it, but if I update an existing entity within a transaction a query within the same transaction will return the updated entity. That explains why in the example I posted the assert fails.

I just reread the documentation and I think it could be more clear on this point, other than that the new documentation is great, thanks for that effort!

Cheers,
Moritz.
Reply all
Reply to author
Forward
0 new messages