Spring Data Neo4j实体类定义复合主键报错及正确实现方法
Spring Data Neo4j 复合主键的正确定义方式
你遇到的错误根源在于Spring Data Neo4j不支持JPA的@EmbeddedId和@Embeddable注解,这两套注解是关系型数据库JPA的专属机制,直接套用会导致节点ID映射冲突。
Spring Data Neo4j定义复合主键的标准方式是使用@IdClass注解,配合主键类实现Serializable并重写equals()和hashCode()方法,具体实现如下:
1. 定义复合主键类
主键类必须实现Serializable,并且重写equals和hashCode方法(Neo4j依赖这两个方法判断节点唯一性):
import java.util.Objects; import java.io.Serializable; public class CustomerId implements Serializable { private String ANumber; private String BNumber; // 必须提供无参构造函数 public CustomerId() {} public CustomerId(String ANumber, String BNumber) { this.ANumber = ANumber; this.BNumber = BNumber; } // 重写equals和hashCode @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; CustomerId that = (CustomerId) o; return Objects.equals(ANumber, that.ANumber) && Objects.equals(BNumber, that.BNumber); } @Override public int hashCode() { return Objects.hash(ANumber, BNumber); } // 补充getter和setter方法 public String getANumber() { return ANumber; } public void setANumber(String ANumber) { this.ANumber = ANumber; } public String getBNumber() { return BNumber; } public void setBNumber(String BNumber) { this.BNumber = BNumber; } }
2. 修改实体类配置
在实体类上添加@IdClass注解指定主键类,并在每个复合主键字段上标注@Id:
import org.springframework.data.neo4j.core.schema.Id; import org.springframework.data.neo4j.core.schema.Node; import org.springframework.data.neo4j.core.schema.IdClass; @Node("customer") @IdClass(CustomerId.class) public class Customer { @Id private String ANumber; @Id private String BNumber; // 其他业务字段及对应的getter/setter // ... // 主键字段的getter/setter public String getANumber() { return ANumber; } public void setANumber(String ANumber) { this.ANumber = ANumber; } public String getBNumber() { return BNumber; } public void setBNumber(String BNumber) { this.BNumber = BNumber; } }
额外说明
- 查询时直接构造
CustomerId对象传入Repository的findById方法即可:CustomerId customerId = new CustomerId("A001", "B001"); Optional<Customer> customer = customerRepository.findById(customerId); - 务必保证主键类的
equals和hashCode逻辑正确,否则会导致节点识别错误。
内容的提问来源于stack exchange,提问作者Morgan
相关产品推荐
相关产品推荐

