1、在用spring data neo4j 连接neo4j 时报了异常:
Caused by: org.neo4j.ogm.exception.core.AmbiguousBaseClassException: Multiple classes found in type hierarchy that map to: [Company, TestCor]
2、用的版本如下:
<spring-boot.version>2.3.12.RELEASE</spring-boot.version> <spring-cloud.version>Hoxton.SR12</spring-cloud.version> <spring-cloud-alibaba.version>2.2.7.RELEASE</spring-cloud-alibaba.version>
spring-boot-starter-data-neo4j是2.3.12.RELEASE org.springframework.data:spring-data-neo4j是5.3.9.RELEASE
3、起因是我给一个节点设置了2个标签(label),在java中给这两个标签定义了两个节点类。然后后就发生了该异常,网上找了很久资料没解决,后面debug源码后发现了原因。
我的标签类(TestCor和Company指向了同一个节点)
@NodeEntity("TestCor") @Data public class CompanyTest { @Id @GeneratedValue private Long id; private String csfId; private String creditCode; private String stdName; private String estiblshTime; private String legalPersonName; private String regCapital; private String ref; }
@NodeEntity("Company") @Data public class Company { @Id private String csfId; private String creditCode; private String stdName; private String estiblshTime; private String legalPersonName; private String regCapital; private String ref; }
3、原因:spring data neo4j 的MetaData.resolve (String... taxa)方法会根据标签去找对应的java节点类(如根据”Company“标签找到Company.java类)。当传入taxa参数超过一个时,他会去判断多个标签之间是不是父子关系,如果不是父子关系就放入Set<ClassInfo> resolved 中,如果是父子关系,只保留子类。但是最终他会判断resolved的size,如果>1就报错。
if (resolved.size() > 1) { // Sort so we always get the same order String[] sorted = Arrays.copyOf(taxa, taxa.length); Arrays.sort(sorted); throw new AmbiguousBaseClassException(Arrays.toString(sorted)); }
有兴趣的可以去看下MetaData.java 类resolve方法,就明白了。
public ClassInfo resolve(String... taxa)方法,这个taxa参数就是neo4j返回的labels,如我的是:
"labels": [ "Company", "TestCor" ],
4、解决办法,让多标签的类继承下就可以解决这个问题了,如我的是:
public class CompanyTest extends Company {
}
5、遗留问题
这样继承后会导致多解析,这个目前没找到解决办法。
6、思考
这个问题不懂是neo4j数据库的问题呢,还是算spring data neo4j 的问题。在查询数据时其实已经根据关系过滤数据了,但是还是返回了多个labels
按理说spring data neo4j应该要根据查询语句上定义的节点类来传labels,但是他又用neo4j返回的labels来处理。
7、总结
个人观点是同节点多labels还是少用。
如果有其他解决方法或是发现是由其他原因导致这个问题的,欢迎交流。