Spring Data Neo4j枚举作节点时findAll报错:Required property $enum$name未找到
问题描述
我使用Spring Data Neo4j操作Neo4j数据库,应用中包含Variation节点实体,其与名为Type的枚举存在关联关系,简化代码如下:
@Node public class Variation extends BaseEntity { private String title; @Relationship(type = "HAS_ATTRIBUTE", direction = Relationship.Direction.OUTGOING) private Type type; // Other fields and relationships... } @Node public enum Type { CUSTOM(0), FIX(1), // Other constants... @Id private final int id; Type(int id) { this.id = id; } }
build.gradle依赖配置:
dependencies { implementation 'org.springframework.boot:spring-boot-starter-data-neo4j' implementation 'org.springframework.boot:spring-boot-starter-web' testImplementation 'org.springframework.boot:spring-boot-starter-test' testRuntimeOnly 'org.junit.platform:junit-platform-launcher' implementation 'org.projectlombok:lombok' annotationProcessor 'org.projectlombok:lombok' }
通过VariationService创建节点和关系后,调用VariationRepository的findAll方法时出现如下错误:
java.lang.IllegalStateException: Required property $enum$name not found for class org.com.example.node.Type at org.springframework.data.mapping.PersistentEntity.getRequiredPersistentProperty ...
疑问:
- 如何配置Spring Data Neo4j以正确映射Type这类枚举作为节点?
- 在Spring Data中处理Neo4j的枚举属性是否有特定方式?
解决方案
1. 正确映射枚举作为Neo4j节点的配置
当前错误是因为Spring Data Neo4j(SDN)处理枚举节点时,默认期望枚举拥有$enum$name属性存储枚举常量名称,但你的Type枚举仅定义了id作为@Id属性,缺少该特殊属性的映射。
修复方式很直接,给Type枚举添加$enum$name属性并赋值:
@Node public enum Type { CUSTOM(0), FIX(1); @Id private final int id; @Property(name = "$enum$name") private final String name; Type(int id) { this.id = id; this.name = this.name(); // 直接获取枚举常量的名称赋值 } }
SDN内部依赖这个$enum$name属性匹配数据库节点与枚举实例,所以必须显式定义并赋值。
2. Spring Data Neo4j处理枚举的两种场景及对应方式
SDN中处理枚举分两种典型场景,对应不同的处理规则:
场景一:枚举作为独立节点(当前场景)
枚举会被映射为Neo4j中的独立节点,需遵循以下规则:- 必须有
@Id标注的属性(支持int、String等类型) - 必须包含
$enum$name属性,用于存储枚举常量名称,SDN通过该属性完成数据库节点到枚举实例的匹配 - 每个枚举常量对应数据库中的一个独立节点
- 必须有
场景二:枚举作为实体的普通属性(非节点)
若无需将枚举映射为独立节点,只需作为实体字段使用,不需要给枚举添加@Node注解:@Node public class Variation extends BaseEntity { private String title; // Type无需@Node注解,直接作为属性 private Type type; } // 枚举无需@Node注解 public enum Type { CUSTOM(0), FIX(1); private final int id; Type(int id) { this.id = id; } }此时SDN默认存储枚举的名称(如"CUSTOM")作为属性值,也可通过
@Enumerated注解指定存储枚举的序号:@Enumerated(EnumType.ORDINAL) private Type type;
内容的提问来源于stack exchange,提问作者it_would_be_better
相关产品推荐
相关产品推荐

