2

My project is currently use Spring-Data-Neo4J 3.3.0 and I'm trying to use the new 4.0.0.Release version. In my code I have the following code :

neo4jTemplate.createRelationshipBetween(eltOrRel, attribute, valueClass, GraphRelationType.HAS_ATT_VALUE, true)

What is the equivalent of this code (which is use this method in api in the new version of SDK please ?

More especially I don't know how to create a relation of a given type but for a specific class. How can I write such a creation in cypher please ?

@Luanne Here is a little example of my problem.

Class Element :

@NodeEntity
public class Element {

@GraphId
private Long id;

private int age;

private String  uuid;

@Relationship(type = "HAS_ATT_VALUE")
private Set<HasAttValue> values = new HashSet<HasAttValue>();
...

Class Attribute :

@NodeEntity
public class Attribute {
@GraphId
private Long id;

private String attName;

And class HasAttValue :

@RelationshipEntity(type = "HAS_ATT_VALUE")
public class HasAttValue {

@GraphId
private Long id;

@StartNode
Element element;

@EndNode
Attribute attribute;

private String value;

public HasAttValue() {
}

public HasAttValue(Element element, Attribute attribute, String value) {
    this.element = element;
    this.attribute = attribute;
    this.value = value;
    this.element.getValues().add(this);
}

In this first case, everything works like a charm, and, as in your example I have the following graph (seeing in the server browser) with my value on the HAS_ATT_VALUE relationshipEntity:

(Element)->[HAS_ATT_VALUE]->(attribute)

But my problem is in the following case (which was working well with previous SDN). Instead of the HasAttValue previous class, I have :

@RelationshipEntity(type = "HAS_ATT_VALUE")
public abstract class HasAttValue<T> {

@GraphId
private Long id;

@StartNode
Element element;

@EndNode
Attribute attribute;

private T value;

public HasAttValue() {
}

public HasAttValue(Element element, Attribute attribute, T value) {
    this.element = element;
    this.attribute = attribute;
    this.value = value;
    this.element.getValues().add(this);
}

with for example two subclasses. First one :

public class HasBooleanValue extends HasAttValue<Boolean> {

public HasBooleanValue() {
}

public HasBooleanValue(Element elt, Attribute attribut, Boolean value) {
    super(elt, attribut, value);
}
}

Second one :

public class HasStringValue extends HasAttValue<String> {

private String locale;

public HasStringValue() {
}

public HasStringValue(Element element, Attribute attribut, String value)   {
    super(element, attribut, value);
}

In this case the graph is like the following :

(element)->[HAS_ATT_VALUE]->(HasBooleanValue|HasStringValue)->[ATTRIBUTE]->(Attribute)

and another arc in the graphe (element)<-[ELEMENT]-(HasBooleanValue|HasStringValue)

So how can I do to always have (element)->[HAS_ATT_VALUE]->(attribute) where "has_att_value" is a relationshipentity containing datas but having diffent impletations in my java code ? Again, this was working well in SDN3 when I used the neo4jTemplate.createRelationshipBetween(eltOrRel, attribute, valueClass, GraphRelationType.HAS_ATT_VALUE, true) to create my "hasAttValue" relationshipEntity.

Thank you very much

clement
  • 489
  • 1
  • 5
  • 18

1 Answers1

3

In SDN 4.0, relationships do not need to be created explicitly using Neo4jTemplate methods. Persisting the entity on which @Relationships are defined is enough to create relationships. If you have properties on the relationship, then you'd need a @RelationshipEntity.

An explanation of object models in SDN 4.0 can be found here http://graphaware.com/neo4j/2015/09/03/sdn-4-object-model.html

Update based on additional info from @clement:

Just move the @RelationshipEntity annotation from the HasAttValue class to each subclass, for example

@RelationshipEntity(type = "HAS_ATT_VALUE")
public class HasBooleanValue extends HasAttValue<Boolean> {

Note that you will need the latest OGM snapshot since an issue around abstract relationship entities was just fixed. Please use

  <dependency>
       <groupId>org.neo4j</groupId>
       <artifactId>neo4j-ogm</artifactId>
       <version>1.1.3-SNAPSHOT</version>
  </dependency>
 <repository>
       <id>neo4j-snapshots</id>
       <url>http://m2.neo4j.org/content/repositories/snapshots</url>
       <snapshots>
           <enabled>true</enabled>
       </snapshots>
  </repository> 

Or use the SDN 4.1 snapshot

<dependency>
    <groupId>org.springframework.data</groupId>
    <artifactId>spring-data-neo4j</artifactId>
    <version>4.1.0.BUILD-SNAPSHOT</version>
</dependency>

Then your graph should look like

enter image description here

Using Cypher directly is not a good idea as you'd have to be able to look up the nodes (maybe by ID), which would mean they have to be saved first.

Luanne
  • 19,145
  • 1
  • 39
  • 51
  • Yes I know that and I already use @ RelationshipEntity. My @ StartNode is of type Element.class and my @ EndNode is of type Attribut.class. But the class on which I add this annotation has subclasses (class A and class B) in which properties can be a little bit different. I do not want to create two different Sets in my Element.class (one for type A and one for type B) but I want to keep only one set of datas (in which I have A and B Objects). That works perfectly in SDN3 but I don't know how to do that with SDN4. How can I write such a Cypher request ? – clement Sep 21 '15 at 13:18
  • I come back to you because after few tests I realize that datas comming back from the graph to java are not convert into the good type. For example, I saved a HasBooleanValue and, when I get this data in another session my data is of type HasDateValue ... That's not a good point at all. Moreover, when I look to graphe in server browser there is no information on "HAS_ATT_VALUE" relation that indicate which type is to use. However I switched to neo4j-ogm 1.1.6-SNAPSHOT. Any idea about that ? – clement Sep 25 '15 at 14:34
  • Hmm, good point. There will not be any extra info on the relationship except properties in the relationship entity. That's why when the relationship is read, there is nothing to tell us what subclass to instantiate (the OGM does not inspect properties). This is something the team will have to discuss- could you please open an issue at https://github.com/neo4j/neo4j-ogm ? (BTW there is no 1.1.6-SNAPSHOT, it's 1.1.3-SNAPSHOT) – Luanne Sep 25 '15 at 15:52