I'm writing an app to capture configuration properties of other applications. Config
is my primary domain object. There are hierarchical relationships between Config
objects (one Config
[:OVERRIDES] another Config
). So, given a bottommost Config
, I need to go all the way up the hierarchy to the topmost Config
, and gather all the properties of Config
objects along the way, merging them into one final Config
. But I have no idea how to do this with Spring Data.
Here is the schema for 2 Config
objects:
CREATE (c1:Config {name:'ConfigParent'});
SET c2.docker_tag='1.0.0';
SET c2.mem_limit='1gb';
MATCH (c1:Config {name: 'ConfigParent'})
CREATE (c2:Config {name:'ConfigChild'})-[:OVERRIDES]->(c1)
SET c2.docker_tag='1.0.1';
The ConfigChild
properties need to be merged with ConfigParent
, and any duplicate properties in ConfigParent
will be overridden. So my final set of properties should be:
name='ConfigMerged' //I don't know what this name would be?
docker_tag='1.0.1'
mem_limit='1gb'
There can be ANY key/value pair in a Config
, so they can't be returned by name. I've come of with this CQL that I think does what I want:
MATCH p = SHORTESTPATH((c2:Config)<-[:OVERRIDES*]-(c1:Config))
WHERE c1.name = 'ConfigChild' and not (c2)-[:OVERRIDES]->()
UNWIND NODES(p) as props return PROPERTIES(props);
The JSON response looks like so:
[
{
"keys": [
"properties(props)"
],
"length": 1,
"_fields": [
{
"name": "ConfigParent",
"docker_tag": "1.0.0",
"mem_limit": "1gb"
}
],
"_fieldLookup": {
"properties(props)": 0
}
},
{
"keys": [
"properties(props)"
],
"length": 1,
"_fields": [
{
"name": "ConfigChild",
"docker_tag": "1.0.1"
}
],
"_fieldLookup": {
"properties(props)": 0
}
}
]
The problem is, I have no idea how to map this to POJOs. Do I need a Config
domain object, or a Properties
domain object? Is this the best CQL to achieve my goal?
UPDATE: I've come up with an annotated POJO for Config
. But when I try to return it in code, properties
are always empty, along with parentConfig
.
@NodeEntity
public class Config {
@Id
@GeneratedValue
private Long id;
@Relationship(type = "OVERRIDES")
private Config parentConfig;
@Properties(allowCast=true)
private Map<String, String> properties;
....
}
This is the basic query I'm testing, just to see if I can map to the POJO:
@Query("MATCH (c1:Config) RETURN c1;")
List<Config> findConfigAny(@Param("configName") String configName);