【发布时间】:2014-12-01 01:23:00
【问题描述】:
我想使用 Spring-Data Neo4j 在 Neo4j 中对包含公司及其业务关系的图表进行建模。所以我为公司创建了节点,为业务关系创建了边缘。然而,有一堆不同类型的关系(买方、供应商、制造商等和一个通用版本“DOES_BUSINESS_WITH”)。每个关系都有一个属性,即目标公司的源公司的内部 ID,例如采购员对每个供应商都有一个内部 ID。并且每一对公司在每个方向上都可以有一个类型的关系。
我的设置方式是为公司设置一个@NodeEntity,为每个不同的业务关系设置一个@RelationshipEntity。由于所有这些关系都具有相同的属性,它们都扩展了泛型类并简单地将正确的标签添加到边缘:
@RelationshipEntity(type="DOES_BUSINESS_WITH")
public class BusinessRelation {
@GraphId
private Long id;
@Fetch
@StartNode
private Company from;
@Fetch
@EndNode
private Company to;
@Indexed
private String knownAsId;
// getters and setters omitted
}
@RelationshipEntity(type="SUPPLIER")
public class SupplierRelation extends BusinessRelation {
public SupplierRelation() {
}
}
由于我有很多不同的关系,我想使用一个存储库接口来处理所有这些。
现在,当我获得关系时,我想在(已经存在的)公司之间建立新的关系,或者在必要时修改现有的关系。所以我决定像这样使用 CREATE UNIQUE 密码子句:
public interface BusinessRelationRepository extends GraphRepository<BusinessRelation> {
@Query(value="match (source:Company {orgId:{0}}),(target:Company {orgId:{1}}) create unique (source)-[r:SUPPLIER]->(target) return r", elementClass=SupplierRelation.class)
SupplierRelation createSupplierMarker(String sourceOrgId, String targetOrgId);
// ...
}
不幸的是,这引发了异常:
org.springframework.dao.DataRetrievalFailureException: No such property, '__type__'.; nested exception is org.neo4j.graphdb.NotFoundException: No such property, '__type__'.
at org.springframework.data.neo4j.support.Neo4jExceptionTranslator.translateExceptionIfPossible(Neo4jExceptionTranslator.java:66)
at org.springframework.data.neo4j.support.Neo4jTemplate.translateExceptionIfPossible(Neo4jTemplate.java:448)
at org.springframework.data.neo4j.support.Neo4jTemplate.doExecute(Neo4jTemplate.java:459)
at org.springframework.data.neo4j.support.Neo4jTemplate.access$000(Neo4jTemplate.java:87)
at org.springframework.data.neo4j.support.Neo4jTemplate$2.doInTransaction(Neo4jTemplate.java:471)
at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:133)
at org.springframework.data.neo4j.support.Neo4jTemplate.exec(Neo4jTemplate.java:468)
at org.springframework.data.neo4j.repository.query.GraphRepositoryQuery.execute(GraphRepositoryQuery.java:82)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:421)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:381)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:98)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:262)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:95)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207)
at com.sun.proxy.$Proxy65.createSupplierMarker(Unknown Source)
我希望将 elementClass 属性添加到 @Query 注释可以为 SDN 提供足够的信息以将结果映射回所需的 SupplierRelation,但它没有。它实际上没有任何效果。
我可以通过自己将 __type__ 属性添加到 Cypher 查询来解决该问题,但是我的代码对 Spring Data Neo4j 的内部工作原理的了解比我想要的要多。所以这行得通:
@Query(value="match (source:Company {orgId:{0}}),(target:Company {orgId:{1}}) create unique (source)-[r:SUPPLIER {__type__:\"SupplierRelation\"}]->(target) return r")
SupplierRelation createSupplierMarker(String sourceOrgId, String targetOrgId);
有没有更好的解决方案不需要我在代码中设置 __type__ 属性?
【问题讨论】:
标签: spring neo4j cypher spring-data-neo4j