Spring Data Neo4j saving is too slow (6s)

@Getter
@Setter
@ToString
@JsonInclude(JsonInclude.Include.NON_EMPTY)
@Node("HeadOrganization")
public class HeadOrganization {

@Id  
@GeneratedValue(UUIDStringGenerator.class)  
private String headOrgUUID;  

@NotNull(message = "headOrgType must not be blank!")  
private OrgType headOrgType;  

private PracticeType practiceType;  

@NotNull(message = "headOrgName must not be blank!")  
private String headOrgName;  

@NotNull(message = "taxpayerIN must not be blank!")  
private String taxpayerIN;  

private String abbreviateName;  

private String code;  

@NotNull(message = "tenant must not be blank!")  
@Valid  
@Relationship(type = "BELONG", direction = Relationship.Direction.OUTGOING)  
private Tenant tenant;  

@NotNull(message = "registration must not be blank!")  
@Valid  
@Relationship(type = "BELONG", direction = Relationship.Direction.OUTGOING)  
private Registration registration;  

@Relationship(type = "OWN", direction = Relationship.Direction.OUTGOING)  
@Valid  
private Set<Setting\> settings \= new HashSet<>();  

@Relationship(type = "HAS", direction = Relationship.Direction.OUTGOING)  
private List<Organization\> subOrgs;  

@Valid  
@NotNull(message = "account must not be blank!")  
@Relationship(type = "HAS", direction = Relationship.Direction.OUTGOING)  
private Account account;  

@Valid  
@Relationship(type = "HAS", direction = Relationship.Direction.OUTGOING)  
private List<Listing\> vipListings;  

@Valid  
@NotNull(message = "address must not be blank!")  
@Relationship(type = "LOCATE", direction = Relationship.Direction.OUTGOING)  
private Address address;  

@Valid  
@NotNull(message = "contactWay must not be blank!")  
@Relationship(type = "CONTACT\_WAY", direction = Relationship.Direction.OUTGOING)  
private ContactWay contactWay;  

@CreatedDate  
@Property    @JsonFormat(locale = "en", pattern = "yyyy-MM-dd HH:mm:ss")  
private Date createDate;  

@LastModifiedDate  
@Property    @JsonFormat(locale = "en", pattern = "yyyy-MM-dd HH:mm:ss")  
private Date lastModifiedTime;  

@Property  
private String timezone \= ZoneId.of("UTC").getId();  

}

@Getter
@Setter
@ToString
@JsonInclude(JsonInclude.Include.NON_EMPTY)
@Node("Organization")
public class Organization {

@Id  
@GeneratedValue(UUIDStringGenerator.class)  
private String orgUUID;  

private OrgType orgType;  

@NotNull(message = "layerSequence must not be blank! ")  
@Min(value = 1)  
private Integer layerSequence;  

@NotNull(message = "orgName must not be blank! ")  
private String orgName;  
private String abbreviateName;  

private String code;  

@Valid  
@Relationship(type = "CHILD\_ORG", direction = Relationship.Direction.OUTGOING)  
private List<Organization\> subOrgs \= new ArrayList<>();  

@Valid  
@Relationship(type = "HAS", direction = Relationship.Direction.OUTGOING)  
private SubAccount subAccount;  

@Valid  
@Relationship(type = "HAS", direction = Relationship.Direction.OUTGOING)  
private List<Listing\> vipListings \= new ArrayList<>();  

@Valid  
@Relationship(type = "OWN", direction = Relationship.Direction.OUTGOING)  
private Set<Setting\> settings \= new HashSet<>();  

@Valid  
@Relationship(type = "LOCATE", direction = Relationship.Direction.OUTGOING)  
private Address address;  

@Valid  
@Relationship(type = "CONTACT\_WAY", direction = Relationship.Direction.OUTGOING)  
private ContactWay contactWay;  

@CreatedDate  
@JsonFormat(locale = "en", pattern = "yyyy-MM-dd HH:mm:ss")  
private Date createDate;  

@LastModifiedDate  
@JsonFormat(locale = "en", pattern = "yyyy-MM-dd HH:mm:ss")  
private Date lastModifiedTime;  

private String timezone \= ZoneId.of("UTC").getId();  

}

@Transactional
public Organization regNormalOrganization(RegisterOrgVO registerOrgVO) {
Organization org = registerOrgVO.getOrg();
checkSettingKey(org.getSettings());
String parentOrgUUID = registerOrgVO.getParentOrgUUID();
if (parentOrgUUID == null) {
Optional<HeadOrganization> headOPT = headOrganizationRepo.findById(registerOrgVO.getHeadOrgUUID());
if (!headOPT.isPresent()) {
throw new RuntimeException("ERROR: headOrgUUID is not correct! registerOrgVO:" + registerOrgVO);
}
HeadOrganization head = headOPT.get();
head.getSubOrgs().add(org);
headOrganizationRepo.save(head);
} else {
Optional<Organization> parentOrgOPT = orgRepo.findById(parentOrgUUID);
if (!parentOrgOPT.isPresent()) {
throw new RuntimeException("ERROR: parentOrgUUID is not correct! registerOrgVO:" + registerOrgVO);
}
Organization parentOrg = parentOrgOPT.get();
parentOrg.getSubOrgs().add(org);
orgRepo.save(parentOrg);
}
return org;
}

ppm10103_0-1672257980117.png

Hi. I have two questions just to get into the right direction:
Is the request processed this slow all the time or is it on the first interaction with the application? I ask this because when making the first query to the database via SDN the driver will get also create its very first connection and this takes time. Of course usually not 6 seconds but it could add up to the response time, you are observing.

Second: Because I cannot see the payload in your question completely, could you give me a rough number of related entities, you want to persist? I assume right now that this POST request does add something to an already existing node that already has a lot of relationships, but want to be sure.

Something you could do to improve the time it takes SDN to update the data is to introduce RelationshipProperties in your domain definition. The update for domains with a lot of relationships usually takes a lot of time because SDN will remove and re-create (if needed) all relationships. This is due to the intentionally non-existing cache to track changes between loading and persistence. Using RelationshipProperties will make relationships no longer anonymous but require those classes to define an id field. This field is used to determine if a relationship is new and needs to get created, or if it got removed from the Java model and also needs to get removed from the database. In the end there are far much less delete and create operations on relationships than before.