Hello! Is there anybody to answer to my previous email? Thanks! Michel
2011/9/2 Michel Domenjoud <[email protected]> > Hi, > I'm currently testing Spring Data Graph, with a focus on polyglot > persistence use cases, in order to give a short presentation at Spring User > Group in Paris on September. > This email follows my previous discussion with Michael Hunger (pasted > below), and I have some questions/suggestions: > > 1- Add a real detached state for entities: > In my previous discussion, I was a bit worrying about the behaviour of Node > Entities which make all getters calls doing a read through in the graph > database, even if we are not in a transaction. > If I understood it correctly, there is indeed no real detached state for > node entities. > I think this is really an issue because it doesn't correspond to the domain > centric purpose of Spring Data. IMHO, this is a semantic problem: if my > NodeEntities are domain objects, I expect that a getter call is immutable, > and so that it is not a read from database operation (at least once I'm out > of a transaction). > > => Imagine I have a big process, for example a computation engine using > nodes entities retrieved from the graph, with long computation, and output > to a file, or another storage engine: > -With the current behaviour, the only way to be sure that all properties of > a Node Entity are immutable when doing some processes is either to keep a > transaction opened during the whole process, either using clones for all > nodes. > - Keeping a very long transaction, knowing I may use many nodes is IMHO > definitly a bad idea. > - I can clone my entities, but I think this is not a good idea too, as I > will use exactly the same class without any backing Node. > => This matter can be really more confusing when using cross-store > persistence, as JPA entities have real detached state. > To answer to Michael, I don't think this must always goes with complicated > Fetch strategies : you could implement a Lazy loading, which would only > retrieve node properties by default, then the developper would need to > retrieve relationships and related Nodes using an explicit call. > > 2. persist() operation is a bit confusing and could lead to mistakes: I'd > suggest to separate it in two methods, save and merge. > > 3. Cross-store persistence: Allow explicit re-attaching JPA side operation. > > Currently, when retrieving a partial NodeEntity from graph database, its > JPA is automatically retrieved. On the other side, when retrieving an entity > from relationnal database, I have to make an explicit call to persist() to > merge the graph side. > => I think this can lead to errors, and performances leaks, by example: > I use a Traversal to retrieve some partial entities in order to update > them, but only for graph side properties. This will work, but for each > retrieved entity a implicit JPA merge call will be done... > > 4- Last question: what are the forecasts about Cross-store persistence API > in Spring Data Graph? Are you planning to make some enhancements on it, or > is it just some sugar over Spring Data Graph API? > > Thanks by advance for your answers! > Michel > > Hi Michael, >> Ok, I get your point now. In fact, the thing I didn't understand yet was >> that each get call on an entity can be compared as a SELECT on relational >> db, even no explicit call to the graph repository is done. >> >> So, if I understand well, I'd improve the documentation by adding somthing >> like that after the paragraph >> Existing > 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. >> Add this after > However, all entities are still attached when reading >> fields, as all gettters will read through the last data in the graph. For >> people used to develop with relationnal databases, this must be undestood >> as each getter call can be assimiled to a SELECT operation. >> >> Finally, I understand your point about read-through vs. fetch strategies >> issues, but this only means that developpers will have to code this glu by >> themselves on each application. I think that if SDG is intended to become a >> reference for using graph database, this kind of API will have to come with >> it one day (but maybe am I misleading because I'm too used to relationnal >> DB). >> >> Moreover, I see one point that could be really confusing with this >> approach in SDG : cross-store persistence. With this API, you provided the >> capability to manage JPA entities, which can use various fetch strategies, >> and Graph entities which use read through, in the same entity class. >> This point is not mentionned is the documentation, I think you should add >> a big warning about this. Something like: >> > As mentionned on Chapter 18.8 Detached node entities, node entities are >> using read-through. On the other side, JPA entities can use various fetch >> strategies. This point must be considered with caution when developping >> applications. >> >> HTH, and more questions will certainly come about cross-store persistence! >> :) >> >> Michel >> >> - Masquer le texte des messages précédents - >> 2011/8/23 Michael Hunger <[email protected]> >> - Masquer le texte des messages précédents - >> 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: >> - Masquer le texte des messages précédents - >> >> > 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 <[email protected]> >> >> Subject: Re: [Neo4j] [Spring Data Graph] Precisions about Detached >> >> Entities and SDG under the hood >> >> To: Neo4j user discussions <[email protected]> >> >> Message-ID: <[email protected] >> >>> >> >> 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: >> >> >> - Masquer le texte des messages précédents - >> >>> 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 testUpdatingEntitiesNotInTrans >> action(){ >> >>> 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 [email protected] https://lists.neo4j.org/mailman/listinfo/user

