复合外键 JPA TypeMismatchException
Composite foreign key JPA TypeMismatchException
我已经通过简单的 Parent Child tables 解释了我的场景。
我的复合主键也是一个复合外键引用父table。
create table parent(
code varchar(10) not null,
id int not null,
parentcol varchar(10),
primary key(code,id)
);
create table child(
code varchar(10) not null,
id int not null,
childcol varchar(10) not null,
primary key(code, id),
foreign key(code, id) references parent(code,id)
);
创建的实体(这是通过 Eclipse JPA 插件)
@Entity
@Table(name="parent")
@NamedQuery(name="Parent.findAll", query="SELECT p FROM Parent p")
public class Parent implements Serializable {
private static final long serialVersionUID = 1L;
@EmbeddedId
private ParentPK id;
@Column(length=10)
private String parentcol;
//bi-directional one-to-one association to Child
@OneToOne(mappedBy="parent")
private Child child;
public Parent() {
}
/* getters and setters */
}
@Embeddable
public class ParentPK implements Serializable {
//default serial version id, required for serializable classes.
private static final long serialVersionUID = 1L;
@Column(unique=true, nullable=false, length=10)
private String code;
@Column(unique=true, nullable=false)
private int id;
/* getters and setters */
/** Overridden equals and hashcode **/
}
@Entity
@Table(name="child")
@NamedQuery(name="Child.findAll", query="SELECT c FROM Child c")
public class Child implements Serializable {
private static final long serialVersionUID = 1L;
@EmbeddedId
private ChildPK id;
@Column(nullable=false, length=10)
private String childcol;
//bi-directional one-to-one association to Parent
@OneToOne
@JoinColumns({
@JoinColumn(name="code", referencedColumnName="code", nullable=false, insertable=false, updatable=false),
@JoinColumn(name="id", referencedColumnName="id", nullable=false, insertable=false, updatable=false)
})
private Parent parent;
/* getters and setters */
}
@Embeddable
public class ChildPK implements Serializable {
//default serial version id, required for serializable classes.
private static final long serialVersionUID = 1L;
@Column(insertable=false, updatable=false, unique=true, nullable=false, length=10)
private String code;
@Column(insertable=false, updatable=false, unique=true, nullable=false)
private int id;
/* overridden equals and hashcode */
我正在使用 Spring 数据来保存我的实体,如下所示。 Parent table 包含一条代码为 "code" 且 Id 为 1.
的记录
Child child = new Child();
ChildPK childPK = new ChildPK();
childPK.setCode("code");
childPK.setId(1);
child.setId(childPK);
child.setChildcol("child1");
childRepository.save(child);
当必须插入新记录时,第一个 运行 成功。但问题是在 2 日 运行 必须更新时,让我们说,
child.setChildcol("child2");
我遇到错误
HHH000327: Error performing load command : org.hibernate.TypeMismatchException: Provided id of the wrong type for class com.xebia.eTechLog.entities.Parent. Expected: class com.xebia.eTechLog.entities.ParentPK, got class com.xebia.eTechLog.entities.ChildPK
以防我尝试在子 table 中提供 ParentPk 的参考
@Entity
@Table(name="child")
@NamedQuery(name="Child.findAll", query="SELECT c FROM Child c")
public class Child implements Serializable {
private static final long serialVersionUID = 1L;
@EmbeddedId
private ParentPK id;
@Column(nullable=false, length=10)
private String childcol;
//bi-directional one-to-one association to Parent
@OneToOne
@JoinColumns({
@JoinColumn(name="code", referencedColumnName="code", nullable=false, insertable=false, updatable=false),
@JoinColumn(name="id", referencedColumnName="id", nullable=false, insertable=false, updatable=false)
})
private Parent parent;
它确实有效,但如果父级中有更多字段,它就不会了 class,这是我的真实情况。
您应该使用派生身份。这意味着您应该指出子项对其父项的引用映射了子项的 ID(使用 @MapsId
注释):
@Entity
public class Child implements Serializable {
@EmbeddedId
private ChildPK id;
@Column(nullable=false, length=10)
private String childcol;
@OneToOne
@MapsId // <<< NB
@JoinColumns({
@JoinColumn(name="code", referencedColumnName="code"),
@JoinColumn(name="id", referencedColumnName="id")
})
private Parent parent;
...
}
派生身份在 JPA 2.1 规范的第 2.4.1 节中进行了讨论。
我已经通过简单的 Parent Child tables 解释了我的场景。
我的复合主键也是一个复合外键引用父table。
create table parent(
code varchar(10) not null,
id int not null,
parentcol varchar(10),
primary key(code,id)
);
create table child(
code varchar(10) not null,
id int not null,
childcol varchar(10) not null,
primary key(code, id),
foreign key(code, id) references parent(code,id)
);
创建的实体(这是通过 Eclipse JPA 插件)
@Entity
@Table(name="parent")
@NamedQuery(name="Parent.findAll", query="SELECT p FROM Parent p")
public class Parent implements Serializable {
private static final long serialVersionUID = 1L;
@EmbeddedId
private ParentPK id;
@Column(length=10)
private String parentcol;
//bi-directional one-to-one association to Child
@OneToOne(mappedBy="parent")
private Child child;
public Parent() {
}
/* getters and setters */
}
@Embeddable
public class ParentPK implements Serializable {
//default serial version id, required for serializable classes.
private static final long serialVersionUID = 1L;
@Column(unique=true, nullable=false, length=10)
private String code;
@Column(unique=true, nullable=false)
private int id;
/* getters and setters */
/** Overridden equals and hashcode **/
}
@Entity
@Table(name="child")
@NamedQuery(name="Child.findAll", query="SELECT c FROM Child c")
public class Child implements Serializable {
private static final long serialVersionUID = 1L;
@EmbeddedId
private ChildPK id;
@Column(nullable=false, length=10)
private String childcol;
//bi-directional one-to-one association to Parent
@OneToOne
@JoinColumns({
@JoinColumn(name="code", referencedColumnName="code", nullable=false, insertable=false, updatable=false),
@JoinColumn(name="id", referencedColumnName="id", nullable=false, insertable=false, updatable=false)
})
private Parent parent;
/* getters and setters */
}
@Embeddable
public class ChildPK implements Serializable {
//default serial version id, required for serializable classes.
private static final long serialVersionUID = 1L;
@Column(insertable=false, updatable=false, unique=true, nullable=false, length=10)
private String code;
@Column(insertable=false, updatable=false, unique=true, nullable=false)
private int id;
/* overridden equals and hashcode */
我正在使用 Spring 数据来保存我的实体,如下所示。 Parent table 包含一条代码为 "code" 且 Id 为 1.
的记录Child child = new Child();
ChildPK childPK = new ChildPK();
childPK.setCode("code");
childPK.setId(1);
child.setId(childPK);
child.setChildcol("child1");
childRepository.save(child);
当必须插入新记录时,第一个 运行 成功。但问题是在 2 日 运行 必须更新时,让我们说,
child.setChildcol("child2");
我遇到错误
HHH000327: Error performing load command : org.hibernate.TypeMismatchException: Provided id of the wrong type for class com.xebia.eTechLog.entities.Parent. Expected: class com.xebia.eTechLog.entities.ParentPK, got class com.xebia.eTechLog.entities.ChildPK
以防我尝试在子 table 中提供 ParentPk 的参考
@Entity
@Table(name="child")
@NamedQuery(name="Child.findAll", query="SELECT c FROM Child c")
public class Child implements Serializable {
private static final long serialVersionUID = 1L;
@EmbeddedId
private ParentPK id;
@Column(nullable=false, length=10)
private String childcol;
//bi-directional one-to-one association to Parent
@OneToOne
@JoinColumns({
@JoinColumn(name="code", referencedColumnName="code", nullable=false, insertable=false, updatable=false),
@JoinColumn(name="id", referencedColumnName="id", nullable=false, insertable=false, updatable=false)
})
private Parent parent;
它确实有效,但如果父级中有更多字段,它就不会了 class,这是我的真实情况。
您应该使用派生身份。这意味着您应该指出子项对其父项的引用映射了子项的 ID(使用 @MapsId
注释):
@Entity
public class Child implements Serializable {
@EmbeddedId
private ChildPK id;
@Column(nullable=false, length=10)
private String childcol;
@OneToOne
@MapsId // <<< NB
@JoinColumns({
@JoinColumn(name="code", referencedColumnName="code"),
@JoinColumn(name="id", referencedColumnName="id")
})
private Parent parent;
...
}
派生身份在 JPA 2.1 规范的第 2.4.1 节中进行了讨论。