Hi Michel, they are implicitely detached when modified outside of a transaction. But even in detached mode, for the unmodified fields it still reads through !
Could you point out how the docs could be improved? To make that easier to understand: http://static.springsource.org/spring-data/data-graph/snapshot-site/reference/html/#reference:programming-model:lifecycle They read always through but the db uses a cache of course. Regarding your example with different clients. Assuming the operation persists before #4 the title will be the new one as this is the new state in the db. It is the same as in a relational db, if you do two selects (which the read through is) then you get the value back that is current in the db. I understand your issue though. Right now the only option would be to copy the values that are needed for the output to a separate datastructure if you never want to have that happen. The problem with detaching and copying is that you get quickly into all the annoyances of fetch-depths, fetch-groups etc. again, that's a path I don't want to walk, it leads to hell :) Michael Am 23.08.2011 um 12:55 schrieb Michel Domenjoud: > Michael, > Thanks for your quick answer. > > This leads me to two new points: > > - You said that an entity is attached when freshly loaded, but I found no > way to explicitly detach entities. Am I right? > If so, I think you should update the documentation which is quite confusing > on this point, and explain clearly that detach entities should be used in a > "write-only" mode. > > - Moreover, I think there could be some confusing side effects if entities > always use read-through : > Does this work with a cache or do the entities always read through the > database? > > How would this example behave with two different clients : > > A client X does the following (let's say title property is indexed): > 1. Movie retrievedMovie = movieRepository.findByPropertyValue("Babel"); > 2. output(retrievedMovie.getTitle()) // prepare some output like Web page > 3. ... do some other operations > 4. output(retrievedMovie.getTitle()) // for some reason, a second output is > needed > > In the same time, a client Y executes the following code: > 1. Movie retrievedMovie = movieRepository.findByPropertyValue("Babel"); > 2.retrievedMovie.setTitle("New title")); > 3. retrievedMovie.persist(); > 4. Some other stuff we don't care > > Which should be the value of the movie title for client X on step 4? > > Thanks by advance for your answer. > Michel > > >> Date: Tue, 23 Aug 2011 11:42:13 +0200 >> From: Michael Hunger <michael.hun...@neotechnology.com> >> Subject: Re: [Neo4j] [Spring Data Graph] Precisions about Detached >> Entities and SDG under the hood >> To: Neo4j user discussions <user@lists.neo4j.org> >> Message-ID: <3a2f0a73-6183-4b32-a02a-7219f0a7f...@neotechnology.com >>> >> Content-Type: text/plain; charset=us-ascii >> >> there are two states attached and detached: >> >> an entity is detached when it is created or when it is changed outside of a >> transaction. >> >> Otherwise (when it is freshly loaded, or after persist it is attached). >> >> For detached entities: persist() writes the changed properties and >> relationships to the graph. if attached (and inside of a tx) all changes are >> written directly. >> >> In your example you just overwrote the title with Babel and persisted that >> information to the graph, so the assert should say: >> The retrieved movie is attached, it is never detached, so it always refers >> to the node in the graph (read-through) (the data is _not_ copied). >> >>> assertEquals("Babel", retrievedMovie.getTitle()); >> >> >> Attached entities read their data directly from the underlying node. >> >> HTH >> >> Michael >> >> The model is different to hibernate, as hibernate has no read-through. We >> would have loved not to support detached entities but as they are so common >> in web-frameworks we had to. >> >> The best way of working with SDG is to use domain level service methods >> which are transactional and do the interaction with the graph. Detached >> entities should just be used to (if at all) to persist >> user input (form data) from the UI. >> >> >> >> Am 23.08.2011 um 10:56 schrieb Michel Domenjoud: >> >>> Hello, >>> I'm currently testing some of Spring Data Graph features, and I have a >> few >>> questions about some usages. >>> >>> Could someone explain to me how the following example works? >>> I run the following unit test: >>> >>> @Test >>> public void testUpdatingEntitiesNotInTransaction(){ >>> Movie m = new Movie(); >>> m.setTitle("Leon"); >>> m.persist(); >>> Long id = m.getNodeId(); >>> Movie retrievedMovie = movieRepository.findOne(id); >>> m.setTitle("Babel"); >>> m.persist(); >>> assertEquals("Leon", retrievedMovie.getTitle()); >>> >>> } >>> >>> And the assertion at the end fails, as retrievedMovie.getTitle() equals >>> "Babel" and not "Leon". >>> This point is not really clear in the documentation : >>> Does this occurs because of some cache? If so, is it the Neo4j cache? And >>> what is exactly its scope : thread, session, ...? >>> Or is any call to getters triggering an access to the database because of >>> AspectJ? >>> >>> Anyway, unless I misundestood something, it's a bit confusing. Especially >>> when used to APIs like Hibernate, which don't make any refresh of >> retrieved >>> entities once we are outside of a transaction. >>> >>> When I read this in documentation, I don't expect that any persist >> operation >>> affect other retrieved entities : >>> Changing an attached entity inside a transaction will immediately write >>> through the changes to the datastore. Whenever an entity is changed >> outside >>> of a transaction it becomes detached. The changes are stored in the >> entity >>> itself until the next call to persist(). >>> >>> All entities returned by library functions are initially in an attached >>> state. Just as with any other entity, changing them outside of a >> transaction >>> detaches them, and they must be reattached with persist() for the data to >> be >>> saved. >>> Maybe I have to precise some points : >>> >>> - I'm using Embedded database, with beforeTest cleaning >>> - I don't use any transaction in this test. >>> >>> >>> Thanks by advance for your help! >>> Michel >>> _______________________________________________ >>> Neo4j mailing list >>> User@lists.neo4j.org >>> https://lists.neo4j.org/mailman/listinfo/user >> > _______________________________________________ > Neo4j mailing list > User@lists.neo4j.org > https://lists.neo4j.org/mailman/listinfo/user _______________________________________________ Neo4j mailing list User@lists.neo4j.org https://lists.neo4j.org/mailman/listinfo/user