[英]JPA2: Nested Primary Key class cannot persist as binding null
I'm using JPA 2.x
with EclipseLink 2.5.1
with nested primary key class
as the following: - 我正在将
JPA 2.x
与带有nested primary key class
EclipseLink 2.5.1
结合使用,如下所示:-
1. OS: Windows 7 64 Bits
2. JDK: 1.7.0_65 64 Bits
3. Maven: 3.2.2
4. Arquillian: 1.1.5.Final
5. Container: Glassfish 4 embedded
6. Database: Derby 10.10.2.0 embedded
@Embeddable
public class MasterPk {
@Column(
name = "MASTER_ID",
length = 5
)
private String masterId;
//----> Setter/Getter is omitted
}
@Entity
@Table(name = "MASTER_TAB")
public class Master {
@EmbeddedId
private MaskerPk id;
@Column(
name = "MASTER_NAME",
length = 40
)
private String masterName;
@OneToMany(
mappedBy = "master"
)
private List<Detail> details;
//----> Setter/Getter is omitted
}
@Embeddable
public class DetailPk {
//----> THE NESTED IS HERE.
@Embedded
private MasterPk masterId;
@Column(
name = "DETAIL_ID",
length = 5
)
private String detailId;
//----> Setter/Getter is omitted
}
@Entity
@Table(name = "DETAIL_TAB")
public class Detail {
@EmbeddedId
private DetailPk id;
@Column(
name = "DETAIL_NAME",
length = 40
)
private String detailName;
@MapsId("masterId")
@ManyToOne
@JoinColumns({
@JoinColumn(
name = "MASTER_ID",
referencedColumnName = "MASTER_ID",
nullable = false
)
})
private Master master;
//----> Setter/Getter is omitted
}
MasterPk masterPk = new MasterPk();
masterPk.setId("001"); //there is a 001 existed in the db
DetailPk detailPk = new DetailPk();
detailPk.setMasterId(masterPk);
detailPk.setDetailId("001"); //new detail to persist
Detail detail = new Detail();
detail.id(detailPk);
detail.setDetailName("detail-name");
em.persist(detail);
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence
http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"
version="2.1">
<persistence-unit name="unittest" transaction-type="JTA">
<jta-data-source>jdbc/unittest</jta-data-source>
<class>com.test.MasterPk</class>
<class>com.test.Master</class>
<class>com.test.DetiailPk</class>
<class>com.test.Detail</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<properties>
<property name="eclipselink.ddl-generation"
value="create-tables" />
<property name="eclipselink.ddl-generation.output-mode"
value="both"/>
<property name="eclipselink.application-location"
value="target"/>
<property name="eclipselink.create-ddl-jdbc-file-name"
value="createDDL_ddlGeneration.jdbc"/>
<property name="eclipselink.drop-ddl-jdbc-file-name"
value="dropDDL_ddlGeneration.jdbc"/>
</properties>
</persistence-unit>
</persistence>
When the project starts, all tables are created correctly, especially the primary key
and foreign key
. 项目启动时,将正确创建所有表,尤其是
primary key
和foreign key
。 But when persist
with the coding., there are some trouble about the Detail
as the Detail.masterId.id
is null. 但是当
persist
进行编码时,由于Detail.masterId.id
为null,所以会有一些关于Detail
麻烦。 The EclipseLink
shows me as EclipseLink
我显示为
Column 'MASTER_ID' cannot accept a NULL value.
INSERT INTO DETAIL_TAB (DETAILE_NAME, DETAIL_ID, MASTER_ID)
VALUES (?, ?, ?)
bind => [detail-name, 001, null]
//
//----> We may be noticed that the masterId is not null. It is printed as 001.
//
Query: InsertObjectQuery(Detail(detailName=detail-name,
id=DetailPk(detailId=001,
masterId=(MasterPk(masterId=001))
)
)
)
I double check by printing all field
in this object-graph
and can confirm that the masterId
is not null as well. 我通过打印此
object-graph
所有field
进行仔细检查,并可以确认masterId
也不为null。 I'm not sure if doing something wrong/misunderstanding. 我不确定是否做错了/误解。 Could you please help to advise how to solve this issue?
您能帮忙建议如何解决此问题吗?
@ManyToOne
at the Detail.java
. Detail.java
处修复@ManyToOne
。 It is a typo when copying and pasting to this question Try to add the @Embedded
to the masterId
at the class DetailPk
. 尝试将添加
@Embedded
到masterId
在类DetailPk
。
Edit 1 result still faces the same issue. 编辑1结果仍然面临相同的问题。
detail
and persist
detail
并persist
I create the MasterPk
directly without finding the Master
. 我直接创建
MasterPk
而不找到Master
。
Further question, Should I need to find the Mater
entity for getting its id
and assigning it to the DetailPk
instead of create it directly via new MasterPk();
进一步的问题,我是否需要找到
Mater
实体以获取其id
并将其分配给DetailPk
而不是直接通过new MasterPk();
直接创建它new MasterPk();
? ?
As MasterPK
is an embeddable it should be annotated with @Embedded
: 由于
MasterPK
是可嵌入的,因此应使用@Embedded
进行注释:
@Embeddable
public class DetailPk {
@Embedded
private MasterPk masterId;
...
}
I guess Detail
entity is also missing @ManyToOne
(or it's just intentional?) 我猜
Detail
实体也缺少@ManyToOne
(或者只是故意的?)
@Entity
@Table(name = "DETAIL_TAB")
public class Detail {
...
@MapsId("masterId")
@ManyToOne
@JoinColumns({
@JoinColumn(
name = "MASTER_ID",
referencedColumnName = "MASTER_ID",
nullable = false
)
})
private Master master;
}
Ad Edit 2 广告修改2
The following statement 以下声明
INSERT INTO DETAIL_TAB (DETAILE_NAME, DETAIL_ID, MASTER_ID)
VALUES (?, ?, ?)
bind => [detail-name, 001, null]
means that the owning side of the master-detail relationship (represented by @ManyToOne
association) is null. 表示主从关系的拥有方 (由
@ManyToOne
关联表示)为null。 From JPA point of view this looks as follows: 从JPA的角度来看,它如下所示:
MASTER_ID
column is related to master
field in Detail
entity MASTER_ID
列与Detail
实体中的master
字段相关 Master
entity uses MasterPK
as the primary key Master
实体使用MasterPK
作为主键 Detail
entity references Master
with master
field Detail
实体引用Master
与master
现场 Detail
entity acts as the owner of the relationship it would be good to specify cascading on it, ie @ManyToOne(cascade = CascadeType.PERSIST)
Detail
实体充当关系的所有者,所以最好在其上指定级联,即@ManyToOne(cascade = CascadeType.PERSIST)
Based on the above, to make thing work we would need to set up the owning side , for example: 基于上述内容,要使工作正常,我们需要设置所有者方 ,例如:
Master master = new Master();
master.id(masterPk);
Detail detail = new Detail();
detail.id(detailPk);
detail.setMaster(master); // the owning side of the master-detail relationship
master.setDetail(detail); // mandatory if CascadeType.PERSIST is not defined
em.persist(detail);
This will result in: 这将导致:
INSERT INTO DETAIL_TAB (DETAIL_NAME, DETAIL_ID, MASTER_ID)
VALUES (?, ?, ?)
bind => [detail-name, 001, 001]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.