父项和子项中的 OpenJPA OneToMany 和复合键 table
OpenJPA OneToMany and composite key in parent and child table
我有 table 个复合主键。
Server(key=ServerId)
ServerId|Name
1 |server1
2 |server2
ParentObj(key=ServerId+Code)
ServerId|Code |Title
1 |code1|value1
1 |code2|value2
2 |code1|Value2b
ChildObj(key=ServerId+Code+Name)
ServerId|Code |Name |Value
1 |code1|prop1|val1
1 |code1|prop2|val2
1 |code2|prop1|val1b
2 |code1|prop3|val3
这是我的 Java 个豆子。
@Entity @Table(name="ParentObj") @Access(AccessType.FIELD)
@IdClass(value=ParentObj.PK.class)
@XmlAccessorType(XmlAccessType.PUBLIC_MEMBER)
@XmlRootElement
public class ParentObj {
@Id private long serverId;
@Id private String code;
private String title;
public long getServerId() { return serverId; }
public String getCode() { return code; }
public String getTitle() { return title; }
public static class PK implements Serializable {
private static final long serialVersionUID = 1L;
private long serverId;
private String code;
public long getServerId() { return serverId; }
public void setServerId(long id) { serverId=id; }
public String getCode() { return code; }
public void setCode(String code) { this.code=code; }
}
}
@Entity @Table(name="ChildObj") @Access(AccessType.FIELD)
@IdClass(value=ChildObj.PK.class)
@XmlAccessorType(XmlAccessType.PUBLIC_MEMBER)
@XmlRootElement
public class ChildObj {
@Id private long serverId;
@Id private String code;
@Id private String name;
private String value;
// public getter+setters for each field
public static class PK implements Serializable {
private static final long serialVersionUID = 1L;
private long serverId;
private String code;
private String name;
public long getServerId() { return serverId; }
public void setServerId(long id) { serverId=id; }
public String getCode() { return code; }
public void setCode(String code) { this.code=code; }
public String getName() { return name; }
public void setName(String name) { this.name=name; }
}
}
我一直在尝试 "everything" 创建 OneToMany 映射(ParentObj->ChildObj),但似乎没有任何效果。我不需要 ManyToOne(ParentObj<-ChildObj) link 但如果必须定义一个也没关系。
这是一个遗留数据库,所以我无法插入 auto_increment 标识列或在父项和子项之间创建额外的连接 table。
这个注释在概念上是我想要的,但是 OpenJPA2.x 库不接受多个连接列。
// from parent to zero or more childs
@OneToMany(fetch=FetchType.LAZY)
@JoinColumns({
@JoinColumn(name="server_id", referencedColumnName="server_id"),
@JoinColumn(name="code", referencedColumnName="code")
})
private List<ChildObj> properties;
编辑,回答
OneToMany、ManyToOne 和 EmbeddedId 注释有效。我只尝试读取现有行,但现在还可以。稍后我尝试更新+插入+删除任务。
public class ParentObj {
@EmbeddedId ParentObj.PK pk;
@OneToMany(fetch=FetchType.LAZY, cascade=CascadeType.ALL, mappedBy="parent", orphanRemoval=true)
private List<ChildObj> childs;
public PK getPK() { return pk; }
public void setPK(PK pk) { this.pk=pk; }
public List<ChildObj> getChilds() { return childs; }
...
@Embeddable @Access(AccessType.FIELD)
public static class PK implements Serializable {
private static final long serialVersionUID = 1L;
@Column(nullable=false) private long serverId;
@Column(nullable=false) private String code;
..getters+setters+hashCode+equals functions
}
}
public class ChildObj {
@EmbeddedId ChildObj.PK pk;
@ManyToOne(fetch=FetchType.LAZY, cascade=CascadeType.PERSIST, optional=false)
@JoinColumns({
@JoinColumn(name="serverid", referencedColumnName="serverid", nullable=false),
@JoinColumn(name="code", referencedColumnName="code", nullable=false)
})
private ParentObj parent;
public PK getPK() { return pk; }
public void setPK(PK pk) { this.pk=pk; }
public long getServerId() { return pk.getServerId(); }
public String getCode() { return pk.getCode(); }
public String getName() { return pk.getName(); }
...
@Embeddable @Access(AccessType.FIELD)
public static class PK implements Serializable {
private static final long serialVersionUID = 1L;
@Column(nullable=false) private long serverId;
@Column(nullable=false) private String code;
@Column(nullable=false) private String name;
..getters+setters+hashCode+equals functions
}
}
最简单的方法是创建一个从 ChildObj
到 ParentObj
的关联,类似于以下内容:
@ManyToOne(fetch = FetchType.LAZY, optional = true)
@JoinColumns({
@JoinColumn(name = "serverId", referencedColumnName = "serverId"),
@JoinColumn(name = "code", referencedColumnName = "code")})
private ParentObj parentObj;
然后在 ParentObj
中定义 @OneToMany
关联,如下所示:
@OneToMany(mappedBy = "parentObj", fetch=FetchType.LAZY)
private List<ChildObj> children;
我还建议您将复合键定义为 @Embeddable
类,用作实体中的 @EmbeddedId
引用。这些可嵌入 PK 类 应该是单独的 类(不是内部 类),因为您将单独使用它们来查询相关实体,并且 serialisation of inner classes can cause problems
我有 table 个复合主键。
Server(key=ServerId)
ServerId|Name
1 |server1
2 |server2
ParentObj(key=ServerId+Code)
ServerId|Code |Title
1 |code1|value1
1 |code2|value2
2 |code1|Value2b
ChildObj(key=ServerId+Code+Name)
ServerId|Code |Name |Value
1 |code1|prop1|val1
1 |code1|prop2|val2
1 |code2|prop1|val1b
2 |code1|prop3|val3
这是我的 Java 个豆子。
@Entity @Table(name="ParentObj") @Access(AccessType.FIELD)
@IdClass(value=ParentObj.PK.class)
@XmlAccessorType(XmlAccessType.PUBLIC_MEMBER)
@XmlRootElement
public class ParentObj {
@Id private long serverId;
@Id private String code;
private String title;
public long getServerId() { return serverId; }
public String getCode() { return code; }
public String getTitle() { return title; }
public static class PK implements Serializable {
private static final long serialVersionUID = 1L;
private long serverId;
private String code;
public long getServerId() { return serverId; }
public void setServerId(long id) { serverId=id; }
public String getCode() { return code; }
public void setCode(String code) { this.code=code; }
}
}
@Entity @Table(name="ChildObj") @Access(AccessType.FIELD)
@IdClass(value=ChildObj.PK.class)
@XmlAccessorType(XmlAccessType.PUBLIC_MEMBER)
@XmlRootElement
public class ChildObj {
@Id private long serverId;
@Id private String code;
@Id private String name;
private String value;
// public getter+setters for each field
public static class PK implements Serializable {
private static final long serialVersionUID = 1L;
private long serverId;
private String code;
private String name;
public long getServerId() { return serverId; }
public void setServerId(long id) { serverId=id; }
public String getCode() { return code; }
public void setCode(String code) { this.code=code; }
public String getName() { return name; }
public void setName(String name) { this.name=name; }
}
}
我一直在尝试 "everything" 创建 OneToMany 映射(ParentObj->ChildObj),但似乎没有任何效果。我不需要 ManyToOne(ParentObj<-ChildObj) link 但如果必须定义一个也没关系。
这是一个遗留数据库,所以我无法插入 auto_increment 标识列或在父项和子项之间创建额外的连接 table。
这个注释在概念上是我想要的,但是 OpenJPA2.x 库不接受多个连接列。
// from parent to zero or more childs
@OneToMany(fetch=FetchType.LAZY)
@JoinColumns({
@JoinColumn(name="server_id", referencedColumnName="server_id"),
@JoinColumn(name="code", referencedColumnName="code")
})
private List<ChildObj> properties;
编辑,回答 OneToMany、ManyToOne 和 EmbeddedId 注释有效。我只尝试读取现有行,但现在还可以。稍后我尝试更新+插入+删除任务。
public class ParentObj {
@EmbeddedId ParentObj.PK pk;
@OneToMany(fetch=FetchType.LAZY, cascade=CascadeType.ALL, mappedBy="parent", orphanRemoval=true)
private List<ChildObj> childs;
public PK getPK() { return pk; }
public void setPK(PK pk) { this.pk=pk; }
public List<ChildObj> getChilds() { return childs; }
...
@Embeddable @Access(AccessType.FIELD)
public static class PK implements Serializable {
private static final long serialVersionUID = 1L;
@Column(nullable=false) private long serverId;
@Column(nullable=false) private String code;
..getters+setters+hashCode+equals functions
}
}
public class ChildObj {
@EmbeddedId ChildObj.PK pk;
@ManyToOne(fetch=FetchType.LAZY, cascade=CascadeType.PERSIST, optional=false)
@JoinColumns({
@JoinColumn(name="serverid", referencedColumnName="serverid", nullable=false),
@JoinColumn(name="code", referencedColumnName="code", nullable=false)
})
private ParentObj parent;
public PK getPK() { return pk; }
public void setPK(PK pk) { this.pk=pk; }
public long getServerId() { return pk.getServerId(); }
public String getCode() { return pk.getCode(); }
public String getName() { return pk.getName(); }
...
@Embeddable @Access(AccessType.FIELD)
public static class PK implements Serializable {
private static final long serialVersionUID = 1L;
@Column(nullable=false) private long serverId;
@Column(nullable=false) private String code;
@Column(nullable=false) private String name;
..getters+setters+hashCode+equals functions
}
}
最简单的方法是创建一个从 ChildObj
到 ParentObj
的关联,类似于以下内容:
@ManyToOne(fetch = FetchType.LAZY, optional = true)
@JoinColumns({
@JoinColumn(name = "serverId", referencedColumnName = "serverId"),
@JoinColumn(name = "code", referencedColumnName = "code")})
private ParentObj parentObj;
然后在 ParentObj
中定义 @OneToMany
关联,如下所示:
@OneToMany(mappedBy = "parentObj", fetch=FetchType.LAZY)
private List<ChildObj> children;
我还建议您将复合键定义为 @Embeddable
类,用作实体中的 @EmbeddedId
引用。这些可嵌入 PK 类 应该是单独的 类(不是内部 类),因为您将单独使用它们来查询相关实体,并且 serialisation of inner classes can cause problems