Head's Up! These forums are read-only. All users and content have migrated. Please join us at community.neo4j.com.
11-04-2019 04:49 AM
I just found out about @EnableSpringDataWebSupport and already love the possibility to simply
@PathVariable("id") Contact contact
but 20 seconds after I refactored a Controller to use this awesome feature I came across the need to load an object to depth 2. Of course I took a leap of faith and tried adding @Depth like
@PathVariable("id") @Depth(2) Contact contact
but that doesn't have any effect.
Is there a way to do this or will this be added?
Cheers, ChrisP
11-04-2019 07:23 AM
The @Depth
annotation is meant to be used on your repository methods or in their method parameter definitions. It has no effect if you put this at the same level as your controller method parameters.
11-04-2019 08:38 AM
I know and realize that BUT it would be good to have a depth option for the DomainClassConverter that gives me a materialized domain object ... hence my original question 🙂 ... because the default depth of 1 is sometimes not enough
11-04-2019 11:20 PM
How would that differ from providing the @Depth
information on the method or in the method parameters in the repository? Your use-case seems to be to provide a fixed depth. Why should that be at the controller level since it is completely database related?
Maybe I do not see your idea behind this right now
Here is the section where the usage of it is described in the code example:
https://docs.spring.io/spring-data/neo4j/docs/5.2.1.RELEASE/reference/html/#reference_derived-querie...
11-05-2019 02:39 AM
Servus Gerrit 😉
The depth is extremely use case specific ... one controller/rest endpoint might need the data with depth 0, the other one with depth 1 and yet another one with depth X ... exactly why we can provide a depth parameter to repo.findById(id, depth) ... isn't it?
So why would I lock the depth on the repository level when this can really only be decided at the exact location of where the data is being requested and used?
Pseudo example:
Before @EnableSpringDataWebSupport
getContact(@PathVariable long id) {
Contact c = contactRepo.findById(id, 0).get();
}
getFullContact(@PathVariable long id) {
Contact c = contactRepo.findById(id, 2).get(); // maybe includes addresses and other related stuff
}
With @EnableSpringDataWebSupport
getContact(@PathVariable("id") Contact contact) {
// contact always loaded with depth 1 ... unnecessarily too much for this use-case
}
getFullContact(@PathVariable("id") Contact contact) {
// contact always loaded with depth 1 ... not usable here
}
Seems to me that the whole idea behind repo.findById(id, depth) has been forgotten for @EnableSpringDataWebSupport
Which is why I asked if this will be added in the future in my original post ... I really think this would make sense and considering the fact that we already have an annotation that would fit here (@Depth) that is what I would consider a well-rounded solution 😉
Cheers, Chris
11-05-2019 06:31 AM
Just realized that there is some major issue with this anyway!
Not sure if I am missing something but this is a huge problem:
I have @EnableSpringDataWebSupport on the WebConfig
and in a RestController:
public DTO patchContact(... @PathVariable("id") Contact contact ...) {
contact.setName("AFTER");
contactRepo.save(contact);
}
the new data is stored BUT Contact has a "owner" relation to a User and a User has a "sponsor" relation to another user like (c:Contact)-[:OWNER]->(u:User)-[:SPONSOR]->(s:User)
and the above code KILLS (!!) the sponsor relation!!! OMG!
Where this works just fine (without deleting any relations):
public DTO patchContact(... @PathVariable("id") long id ...) {
Contact contact = contactRepo.findById(id).get();
contact.setName("AFTER");
contactRepo.save(contact);
}
What am I missing here? Isn't the "WebSupport" simply doing a findById() in the background? Is there a problem with TX handling here.... ???
FYI: Just upgraded to Spring framework 5.2.0.RELEASE and spring-data-neo4j 5.2.0.RELEASE as well as neo4j-ogm-bolt-driver 3.2.2 hoping that maybe this problem has been resolved but this very much UNWANTED behavior still remains
11-06-2019 06:25 AM
This will get a little bit longer now:
It is correct that findById
gets triggered with its default depth of 1.
Loading, manipulating and saving an entity should always happen within one transaction because (besides other things) keeping track of the depth the objects were loaded with.
I do not know yet where your @Transactional
boundaries are, if there are any.
If you are using the transactional mechanism you should keep in mind that one transaction is technically one SDN/OGM session in the background with its very own cache and track of the depth.
In the first case the retrieval of the Contact
happens (most likely) in a different transaction than your data manipulation. When saving the entity OGM does not know how "deep" it was fetched before and wants to store all reachable relationships/nodes. Jumping into the second example it looks about the same.
I just assume for now that, because there are a different loading mechanism in WebSupport and plain loading, one collection is empty and the other is null and this leads to the different behaviour.
I wanted to show some reaction because your finding is really valuable to us. We need some time to dig deeper into this and I will come back with more information. I am not yet 100% sure (anymore) if null
or empty makes any difference when the entities should get persisted and it is beyond the loading depth.
11-06-2019 07:25 AM
Thanks for your answer - I am looking forward to hearing about your findings!
FYI @Transactional is at the Controller level
Cheers, Chris
11-12-2019 06:06 AM
Hi Gerrit,
any news on this?
I am starting a new project and would like to use this feature to avoid all the repo.findById(id).get();
calls but only if it doesn't destroy my data.
I would simply assume that the @Transactional
on the Controller is wrapped around the entire request and makes sure that the data loaded by WebSupport runs in the same TX and OGM session as my method body ... otherwise this entire WebSupport feature is not usable in MOST cases anyway?
Cheers, Chris
All the sessions of the conference are now available online