AutoIndex feature gone in SDN 6?

Hello @gerrit.meier

I can't find anything in the SDN docs about indexing ... No more @Index and autoIndex(AutoIndexMode.UPDATE)?

Cheers, Chris

What about repository level events like onPostSave and onPostDelete (from OGM's EventListenerAdapter)?


I had to import OGM and use their labels (@Index) even though I had SDN6 imported. I also had to configure the SessionFactory to enable the autoIndex("update")

Is that really what SDN 6 should be?
We need stuff from the old libs?

I also found out today that (bidirectional) @Relationship mappings don't really work and I wonder if this is by design ... because relationships get deleted!!!

For example:

class A {
  @Relationship List<B> bs;

class B {
  @Relationship A a;

If you now load an A entity, add a new B to the list of bs and save A or B, then all the connections to existing Bs get deleted! Digging into this I found that the Bs in the List have a set to null (do not get hydrated with A when A loads)

Haven't tried other (more complex) mappings yet but I guess it will be even worse and connections will get lost (because things only get loaded to depth 1???)

We intentionally did not re-implement this in SDN 6. The feature itself brought a lot of customer confusions (mainly because of the asynchronous nature of the index creation) but also created a lot of maintenance to handle every support database version right.
And in the end it is not a feature from an O[G/R/*]M but something that should be solved on the database side, say DBA or other tooling. For this we created or you could use

No, please don't ;)

Yes, relationships will get deleted but this should of course not happen if A (and its related entities) were loaded and hydrated. Could you provide an example with a little bit more information about the Node classes (like id type, generated or not..) or even better a failing test scenario.

Also the assumption that we load with depth 1 is wrong because there is no limitation.

Hi @gerrit.meier Thank you for your reply!


The @Index is - was - a REALLY awesome feature because the Java classes are effectively a schema for a schemaless DB and what better place to define which fields should get an index than in the schema?
Without this, it is definitely a step backwards and I have to go back abut 4 years and maintain a file of Cypher statements to drop/create indexes when deploying new app versions :cry:


Also very important and missing now:

  • something like onPreSave e.g. for giving each entity a UUID (in addition to the @Id @GeneratedValue Long id) or some other calculated values
  • onPostSave, onPostDelete for things like updating an external index

@DomainEvents is great for some certain things but not for this (unless I am completely wrong and missing something ? but I can't see how I would get the info if the entity was created/updated/deleted).
Of course I could publish an applicationEvent EVERYWHERE I save/delete an entity but I think it would be much better (and easy to implement?) if Neo4jTemplate & Repositories published some generic Neo4j events that we can listen for (possibly enabling this feature with a @EnableNeo4jEvents).


Importing old libs: Didn't think so, don't want to ;)


Regarding the bidirectional relationship: I haven't used those for years because it always caused problems with OGM and now I thought with the new SDN6 I would give it a try again. So here is a compact version of what I want to do:

public abstract class Node {
	@Id @GeneratedValue @Getter private Long id;
	@Version @Getter private Long version;
	@CreatedDate @Getter private LocalDateTime created;
	@LastModifiedDate @Getter  private LocalDateTime modified;
	@Getter private String uuid; // <-- see nescessary onPreSave above!

public class Page extends Node {
	private String title;
	@Relationship(type = "PAGE", direction = Relationship.Direction.INCOMING) private List<File> files = new ArrayList<>();

public class File extends Node {
	@Relationship(type = "PAGE") private Page page;
	private String name;

// add a new file:
Page page = pageRepo.findById(id).get();
File file = new File();

// option 1:; // deletes all existing connections between page and other files

// option 2:
page.getFiles().add(file);; // also deletes all existing connections between page and other files

// here: only the new file is connected to the page anymore

The existing files [loaded when the page is loaded] all have a getPage() of null (!) and by saving the page [either directly or indirectly through saving the new file] deletes the existing relationships.

Regarding onPreSave / onPostSave / onPostDelete:

I am thinking something like this (not sure if this is really the best way to go but you get my point):

public void handleNeo4jEvent(Neo4jEvent event) {
	if (event.getEntity() instanceof MyBaseNode) {
		if (event.getType() == Neo4jEventType.PRE_SAVE) {
			MyBaseNode node = (MyBaseNode) event.getEntity();
			if (StringUtils.isBlank(node.getUuid())) node.setUuid(UUID.randomUUID().toString());

@TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)
public void handleNeo4jAfterCommit(Neo4jEvent event) {
	if (event.getEntity() instanceof Page) {
		if (event.getType() == Neo4jEventType.SAVED) {
			// update external index or file system
		} else if (event.getType() == Neo4jEventType.DELETED) {
			// delete entry from index, delete files from FS


Actually it would be best to be able to receive events for CREATED, UPDATED and DELETED (not just saved and deleted like my previous post might suggest)

Background: I regularly push info about object C(R)UD events to clients via web-sockets