難住了,徹底難倒了複合主鍵...春數據JPA:無法保存實體包含外鍵
假設兩個實體,父母與子女,與許多子實體父母一方。 Parent的主鍵是java.util.UUID
類型,而Child的主鍵是Parent的UUID和序列號的組合。
短的問題是,當我嘗試保存使用childRepository.save(child)
一個新的孩子,我得到以下異常:
造成的:java.lang.IllegalArgumentException異常:無法轉換 類型[值COM .package.entities.ParentEntity $$ _ jvst149_0]爲所需類型 屬性'parent'的[java.util.UUID]:PropertyEditor [org.springframework.beans.propertyeditors.UUIDEditor]返回 不適當的值爲 [com。 package.entities.ParentEntity _ $$ _ jvst149_0]
請看下面我的課程。最好的,我可以告訴我正確遵循了JPA
規範,所以我不知道如果這是在Spring Data JPA
一個錯誤,也許具體到UUID類型ID(類似的事情以前也發生過,看DATAJPA-269)
注意我用的spring-boot-starter-data-jpa 1.4.1.RELEASE
Parent.java:
@Entity
@Table(name = "parent")
public class Parent implements Serializable {
@Id
@GeneratedValue(generator = "uuid")
@GenericGenerator(name = "uuid", strategy = "uuid2")
private UUID id;
//...other fields, getters + setters...
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Parent that = (Parent) o;
return Objects.equals(id, that.id);
}
@Override
public int hashCode() {
return Objects.hash(id);
}
}
Child.java
@Entity
@Table(name = "child")
@IdClass(ChildKey.class)
public class Child implements Serializable {
@Id
@ManyToOne
@JoinColumn(name = "parent_id", referencedColumnName = "id", insertable = false, updatable = false)
private Parent parent;
@Id
private Integer seqNum;
//...other fields, getters + setters...
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Child that = (Child) o;
return Objects.equals(parent, that.parent) &&
Objects.equals(seqNum, that.seqNum);
}
@Override
public int hashCode() {
return Objects.hash(parent, seqNum);
}
}
ChildKey的.class
public class ChildKey implements Serializable {
private UUID parent;
private Integer seqNum;
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ChildKey that = (ChildKey) o;
return Objects.equals(parent, that.parent) &&
Objects.equals(seqNum, that.seqNum);
}
@Override
public int hashCode() {
return Objects.hash(parent, seqNum);
}
}
ParentRepository.java
@Repository
public interface ParentRepository extends JpaRepository<Parent, UUID> {
}
ChildRepository.java
@Repository
public interface ChildRepository extends CrudRepository<Child, ChildKey> {
}
最後,代碼我執行:
@Transactional
public void createChild(Parent parent) {
// needed to do this to get over "detached entity passed to persist"
parent = parentRepository.getOne(parent.getId());
child = new Child();
child.setParent(parent);
child.setSeqNum(1);
childRepository.save(child);
}
謝謝 - 我很欣賞答案,但我不認爲我會遵循。在我使用過的每個RDBMS中,我從來沒有遇到過一個兒童的主鍵由外鍵組成的問題 - 事實上,這是規範化數據庫的常用策略。 – Jpnh