I just hacked together a proof of concept implementation that stores all key/value pairs of a PropertyMap field of a NodeEntity to the underlying neo4j node. PropertyMap is an newly introduced PropertyContainer like interface (see below). A own FieldAccessorFactory handles getting and setting this field.
Sounds good.
Some kind of FieldAccessorFactory registry would be great. I now ended up configuring the whole Spring Data Graph stuff in XML bean notation, because the java config of course does not know anything about my extended NodeDelegatingFieldAccessorFactory and it has to be wired in manually. May there be simpler alternatives to just "replace" the NodeDelegatingFieldAccessorFactory bean with an own implementation?
Right. You shouldn't need to configure everything in XML just override the definition of "nodeEntityStateFactory" with an equivalent of this bean definition:
PHP Code:
@Bean
public NodeEntityStateFactory nodeEntityStateFactory() throws Exception {
NodeEntityStateFactory entityStateFactory = new NodeEntityStateFactory();
entityStateFactory.setGraphDatabaseContext(graphDatabaseContext());
entityStateFactory.setEntityManagerFactory(entityManagerFactory);
final NodeDelegatingFieldAccessorFactory nodeDelegatingFieldAccessorFactory = new NodeDelegatingFieldAccessorFactory(graphDatabaseContext());
entityStateFactory.setNodeDelegatingFieldAccessorFactory(nodeDelegatingFieldAccessorFactory);
return entityStateFactory;
}
i.e. something like this should be enough
PHP Code:
<bean id="nodeEntityStateFactory" class="NodeEntityStateFactory">
<property name="graphDatabaseContext" ref="graphDatabaseContext"/>
<property name="entityManagerFactory" ref="entityManagerFactory"/>
<property name="nodeDelegatingFieldAccessorFactory">
<bean class="MyNodeDelegatingFieldAccessorFactory">
<constructor-arg ref="graphDatabaseContext"/>
</bean>
</property>
</bean>
The problem with the inlined map is that this map does not know which properties belong to the map and which belong to the entity itself, when it is loaded.
I'd solve that by prefixing the properties with "fieldName." just as you proposed in your initial post. So you can easily filter the properties that belong to your map by iterating over node.getPropertyNames() and filtering for the field.getName() that you can get from your FieldAccessorFactory.
I introduced an interface PropertyMap that is the same as PropertyContainer, but without the getGraphDatabase() method. An implementation of this PropertyMap uses a Map<String, Object> as a delegate to actually store the key/value pairs and is used in the DynamicPropertiesFieldAccessor that handles properties of type PropertyMap.
My next step will be to try to store the dynamic map in a separate node so that I do not have to know which keys are already handled by other FieldAccessors on the entity itself.
Looking forward to that and to merge it into SDG itself.
Thanks a lot for your efforts.
Michael