难倒,完全难倒......
假设两个实体Parent和Child,其中有一个Parent实体到一个Parent。 Parent的主键是java.util.UUID
类型,Child的主键是Parent的UUID和序列号的组合。
问题的关键是当我尝试使用childRepository.save(child)
保存新的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(之前发生过类似的事情,请参阅{{ 3}})
注意我正在使用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);
}
答案 0 :(得分:0)
在多对一关系中,您的子实体拥有自己的ID,而来自父实体的ID是FK而不是PK的一部分。 Example
答案 1 :(得分:0)
自我发布此问题以来的几个月里,我找不到合适的答案。遗憾的是,我不得不使用@ManyToOne
解决问题,而只是通过UUID引用父级:
public class Child implements Serializable {
@Id
private UUID parentId;
@Id
private Integer seqNum;
我让JPA不知道外键,如果违反参考完整性,就让数据库抛出错误。
答案 2 :(得分:0)
您需要更改您的ChildKey类:
public class ChildKey implements Serializable {
private Parent parent; // <-- Parent type instead of UUID
private Integer seqNum;
...
UPD:我读过JPA规范。并且明白这是不正确的。但它适用于我的情况。