How does persistence work with variable depth fetches?


(Joe) #1

I’m just migration to the newest OGM, having had my project on an older version of SDN until now.

I’m worried about something that isn’t very well spelled out in the docs (https://neo4j.com/docs/ogm-manual/current/reference/).

  • 3.7.4.1. Load depth: By default, loading an instance will map that object’s simple properties and its immediately-related objects (i.e. depth = 1).

  • 3.7.3.1. Save depth: As mentioned previously, save(entity) is overloaded as save(entity, depth), where depth dictates the number of related entities to save starting from the given entity. The default depth, -1, will persist properties of the specified entity as well as every modified entity in the object graph reachable from it. This means that all affected objects in the entity model that are reachable from the root object being persisted will be modified in the graph

If I load an object to depth N, I’m presuming that relationships at depth N will not get loaded, and so the associated object properties will be returned null.

If I subsequently resave such a loaded object won’t OGM remove the preexisting relationship?

Or, does OGM know that it didn’t load that subobject and so not remove the relationship? (How does it know?)


(Gerrit Meier) #3

Neo4j-OGM ignores null fields when saving if they were not filled when loading. This is because it diffs the objects' fields fields when saving against the state when they were loaded and cached.

Here is an excerpt from my example test:

Person person = new Person("Bob");
/*...*/
session.save(person);
session.clear(); // clear to simulate a complete new session
	
person = findPersonWithDepth(0);
assertThat(person.getChild()).isNull();
assertThat(person.getAge()).isNull();
assertThat(person.getName()).isEqualTo("Bob");
	
/* change data if wanted */
session.save(person);
session.clear(); // clear to simulate a complete new session
	
person = findPersonWithDepth(1);
assertThat(person.getChild()).isNotNull();
assertThat(person.getAge()).isEqualTo(10);

person.setChild(null);
session.save(person);
session.clear();

person = findPersonWithDepth(1);
assertThat(person.getChild()).isNull();
assertThat(person.getAge()).isNull();