1

I am looking for Composite Attribute example but can not find it everywhere. I have simple class :

@NodeEntity
public class MyClass{
@GraphId Long id;
Double diameter; 
//Property diameter should be from composite attribute (inDiameter and outDiameter)
}

MyClass have property diameter, it should be value from inDiameter or outDiameter (can use both as value with some condition)

And I have the other class like this:

@NodeEntity
public class MyClass2{
@GraphId Long id;
String name; 
//Property name should be from composite attribute (firstName and lastName)
}

How I can achieve that?

Do I need to create class for dummy diameter like this?

//without @NodeEntity
Class NominalDiameter{
     Double outsideDiameter
     Double insideDiameter
}

And I change my property of MyClass :

Double diameter -> NominalDiameter diameter;

I'm using Spring boot parent 1.4.1.RELEASE, neo4j-ogm 2.0.5, Spring Data Neo4j 4

David Vincent
  • 634
  • 1
  • 8
  • 33

1 Answers1

3

In the latest version of OGM - 2.1.0-SNAPSHOT there is a @CompositeAttributeConverter that can be used for this purpose.

Example of mapping multiple node entity properties onto a single instance of a type:

/**
* This class maps latitude and longitude properties onto a Location  type that encapsulates both of these attributes.
*/
public class LocationConverter implements CompositeAttributeConverter<Location> {

    @Override
    public Map<String, ?> toGraphProperties(Location location) {
        Map<String, Double> properties = new HashMap<>();
        if (location != null)  {
            properties.put("latitude", location.getLatitude());
            properties.put("longitude", location.getLongitude());
        }
        return properties;
    }

    @Override
    public Location toEntityAttribute(Map<String, ?> map) {
        Double latitude = (Double) map.get("latitude");
        Double longitude = (Double) map.get("longitude");
        if (latitude != null && longitude != null) {
            return new Location(latitude, longitude);
        }
        return null;
    }

}

To use:

@NodeEntity
public class Person {

   @Convert(LocationConverter.class)
   private Location location;
   ...
}

To depend on this version:

repositories {
    mavenLocal()
    mavenCentral()
    maven { url "http://m2.neo4j.org/content/repositories/snapshots/" }
    maven { url "https://repo.spring.io/libs-snapshot" }
}
Jasper Blues
  • 28,258
  • 22
  • 102
  • 185
  • im using neo4j-ogm 2.0.5, it still don't have CompositeAttributeConverter. I can't use snapshot jar, is there another way? This answer is good thou, but too bad I can't use that, because it still snapshot. – David Vincent Oct 24 '16 at 10:38
  • @DavidVincent Actually, I can't think of another way to do it. Other than use several simple properties. We hope to release 2.1.0 soon. – Jasper Blues Oct 24 '16 at 11:39
  • This is awesome @Jasper Blues! any idea (aprox) when 2.1.0 will be released? – troig Oct 24 '16 at 12:56
  • Yeah, this is so helpful. i'll use a simple properties for now, while waiting for 2.1.0 release version. Thank you – David Vincent Oct 24 '16 at 14:07
  • @JasperBlues btw, is that Location class should be added to database too? Because if I add Location class, it should be hv a lot of data. – David Vincent Oct 24 '16 at 15:58
  • @DavidVincent It will be released with the next release of Spring Data. This feature takes two properties on a node, and maps them into an instance of a class in your `@NodeEntity` - just for logical grouping. No need to add to database. – Jasper Blues Oct 24 '16 at 21:57