Results 1 to 5 of 5

Thread: Spring Data Neo4j: How to map java.util.Map<String,String> field?

  1. #1

    Default Spring Data Neo4j: How to map java.util.Map<String,String> field?

    Hello,

    I have an relationship node class like this :

    @RelationshipNode
    public class MyConnection {
    private String title;
    private long duration;
    private Map<String,String> attributes;
    ...
    }

    When using Spring data Neo4J mapping layer, it naturally creates relationship nodes in Neo4j with keys "title" and "duration" corresponding to names of my class fields, but Map<String,String> field is not persisted. I would like those key-value entries in this Map to be also persisted inside this relationship node also as list of properties, but I understand the problem that I would have to distinguish this map field from other fields.

    I could decide for eg. to add additional prefix, something like "fieldName_" + entry.getKey() for name of property.
    Is it possible somehow to add some loading/saving interceptor in Spring-Data-Neo4j lib so it can work when loading/persisting this class insatnces, or it's not possible so I would have to use low-level Neo4 API for that (Neo4JTemplate)? I don't like later because I don't know how elegant it would be to mix those two approaches in my application.

    Regards,
    Vjeran

  2. #2
    Join Date
    Jan 2011
    Location
    Dresden, Germany
    Posts
    525

    Default

    You would use the DynamicProperties instead of the Map which is then mapped to node-attributes.

    See this test, on how to use it.

    Code:
    @NodeEntity
    public class Person {
        @GraphId
    	private Long graphId;
    
    	private DynamicProperties personalProperties;
    	public void setProperty(String key, Object value) {
    		personalProperties.setProperty(key, value);
    	}
    
    	public Object getProperty(String key) {
    		return personalProperties.getProperty(key);
    	}
    }
    @Test
        public void testCreateOutsideTransaction() {
            Person p = new Person("James", 35);
            p.setProperty("s", "String");
            p.setProperty("x", 100);
            p.setProperty("pi", 3.1415);
            persist(p);
            assertEquals(3, IteratorUtil.count(p.getPersonalProperties().getPropertyKeys()));
            assertProperties(nodeFor(p));
            p.setProperty("s", "String two");
            persist(p);
            assertEquals("String two", nodeFor(p).getProperty("personalProperties-s"));
        }

  3. #3

    Default

    Oh, great!
    Thanx.

  4. #4

    Default

    I noticed a shortcoming with current way of persisting DynamicProperties - this map entries are stored with property names constructed with prefix (derived from DynamicProperties field name) and map key, separated by dash ("-"), and since dash is a special character inside Cypher, it is not simply possible to query these node properties by using query piece such as:

    Code:
    node.prefix-mapkey
    , but one has to use quite unknown "backtick" character for quoting node property name, such as:
    Code:
    node.`prefix-mapkey`
    Therefore, I would suggest that separation character is underscore, which is not treated as special character as I know.

    Regards,
    Vjeran

  5. #5
    Join Date
    Jan 2011
    Location
    Dresden, Germany
    Posts
    525

    Default

    Good point,

    can you raise an JIRA issue? for that

    Better to make it configurable

    Michael

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •