【发布时间】:2023-08-30 13:35:01
【问题描述】:
我正在使用带有 JPA 和 Hibernate 的 SpringBoot。
我有两个实体:书和作者。一本书可以有多个作者。所以我需要一个 OneToMany 关系。
进入 Author 表,我的想法是使用复合键(book_id 和一个内部字段,例如 field_a)
我实现了这些类:
@Entity
@Table(name = "book")
public class Book extends MyBaseEntity {
@Id
@Column(name = "id")
@Type(type = "uuid-char")
private UUID uuid = UUID.randomUUID();
@Column(name = "name", nullable = false)
private String name;
@OneToMany(mappedBy = "book")
private List<Author> authors = new ArrayList<>();
}
@Entity
@Table(name = "author")
public class Author extends MyBaseEntity {
@EmbeddedId
private CustomID id;
@ManyToOne()
@MapsId("bookId")
@JoinColumn(name = "book_id")
private Book book;
@Column(name = "field_a", nullable = false)
@MapsId("fieldA")
@Type(type = "uuid-char")
private UUID fieldA;
}
@Embeddable
public class CustomID implements Serializable {
@Column(name = "book_id")
private UUID bookId;
@Column(name = "field_a")
private UUID fieldA;
public CustomID() { }
public CustomID(UUID bookId, UUID fieldA) {
this.bookId = bookId;
this.fieldA = fieldA;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass())
return false;
ShareID that = (CustomID) o;
return Objects.equals(bookId, that.bookId) &&
Objects.equals(fieldA, that.fieldA);
}
@Override
public int hashCode() {
return Objects.hash(bookId, fieldA);
}
}
当我尝试执行我的项目时(我正在使用属性spring.jpa.hibernate.ddl-auto=create 生成数据库)我收到此错误:
ERROR SpringApplication-reportFailure():837 - [ Application run failed ]
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Invocation of init method failed; nested exception is org.hibernate.AnnotationException: Unknown entity name: java.util.UUID
有什么建议吗?
如果我尝试删除组合键的使用效果很好,那么问题可能与组合键的实现或使用有关。
【问题讨论】:
-
与您的实际问题无关的问题:您真的希望
Book有多个Author,但一个Author只能与一个Book相关吗? -
是的,可能我没有使用最合适的例子......但在我的真实场景中,它的关系是正确的
-
只是问一下,因为从实体结构来看,您似乎采用了有效的多对多关系设置并尝试将其转换为一对多设置。从实体设计的角度来看,复合键对我来说没有多大意义,为什么不直接映射到作者实体中的书?
-
不过也可能是因为我用了太多的Spring Data抽象,太久没用JPA了^^
-
问题是 UUID 'fieldA' 有两个映射。 MapsId 用于关系映射,fieldA 不是,它告诉 JPA 使用此引用实体中的主键来设置您指向它的嵌入式 ID - 'fieldA' 中的值。只需从 Author 类中彻底删除它,并在需要使用该 UUID 时使用 author.id.fieldA。
标签: java spring-boot hibernate jpa