Java 如何与父实体';什么是复合键?

Java 如何与父实体';什么是复合键?,java,hibernate,jpa,groovy,Java,Hibernate,Jpa,Groovy,目前,这些只是查询操作,如果您“获取”父对象,那么您希望获取所有子对象。它是一个遗留数据库(DB2),其中父表中有三个字段是它的复合PK。子表包含这三个字段,还有一个字段作为其复合主键 不需要双向的。只需要让孩子们和父母相处 @Entity @IdClass(ParentId.class) class Parent { @Id int someId @Id int someCode @Id Date someDate @OneToMany(fetch = Fet

目前,这些只是查询操作,如果您“获取”父对象,那么您希望获取所有子对象。它是一个遗留数据库(DB2),其中父表中有三个字段是它的复合PK。子表包含这三个字段,还有一个字段作为其复合主键

不需要双向的。只需要让孩子们和父母相处

@Entity @IdClass(ParentId.class)
class Parent {
    @Id int someId
    @Id int someCode
    @Id Date someDate

    @OneToMany(fetch = FetchType.EAGER, ???)
    ???
    List<Child> children
}

class ParentId implements Serializable {
    int someId
    int someCode
    Date someDate
}

@Entity @IdClass(ChildId.class)
class Child {
    @Id int someId
    @Id int someCode
    @Id Date someDate
    @Id String childValue
    ...
}

class ChildId implements Serializable {
    int someId
    int someCode
    Date someDate
    String childValue
}
@Entity@IdClass(ParentId.class)
班级家长{
@Id int someId
@Id int someCode
@身份证日期
@OneToMany(fetch=FetchType.EAGER,?)
???
列出孩子
}
类ParentId实现可序列化{
内体
内码
约会
}
@实体@IdClass(ChildId.class)
班童{
@Id int someId
@Id int someCode
@身份证日期
@Id字符串子值
...
}
类ChildId实现了可序列化{
内体
内码
约会
字符串子值
}
ChildId类非常类似于父字段加上另一个字段

我是否需要切换到@embeddeble和@embeddedableid等。?不管怎样,有人知道如何使这项工作?我见过一些更简单的例子,对我来说似乎不太合适


我可以更改父类和子类,但不能更改表及其当前复合PK。

您可以使用
@IdClass
@EmbeddedId
。无论哪种方式,您都在使用“派生标识”。以下是使用
@IdClass
的可能解决方案:

@Entity
@IdClass(ParentId.class)
public class Parent {
    @Id int someId;
    @Id int someCode;
    @Id Date someDate;

    @OneToMany(fetch = FetchType.EAGER, mappedBy = "parent")
    List<Child> children;
}

public class ParentId implements Serializable {
    int someId;
    int someCode;
    Date someDate;
    ...
}

@Entity
@IdClass(ChildId.class)
public class Child {
    @Id
    @ManyToOne
    @JoinColumns({
        @JoinColumn(name="PARENT_ID", referencedColumnName="someId"),
        @JoinColumn(name="PARENT_CODE", referencedColumnName="someCode"),
        @JoinColumn(name="PARENT_DATE", referencedColumnName="someDate") 
    })
    Parent parent;
    @Id String childValue;
    ...
}

public class ChildId implements Serializable {
    ParentId parent; // matches name of attribute and type of Parent Id class
    String childValue;
}
@实体
@IdClass(ParentId.class)
公共类父类{
@Id-int-someId;
@Id-int-someCode;
@Id日期someDate;
@OneToMany(fetch=FetchType.EAGER,mappedBy=“parent”)
列出儿童名单;
}
公共类ParentId实现可序列化{
内体;
int-someCode;
约会某天;
...
}
@实体
@IdClass(ChildId.class)
公营儿童{
@身份证
@许多酮
@连接柱({
@JoinColumn(name=“PARENT\u ID”,referencedColumnName=“someId”),
@JoinColumn(name=“PARENT\u CODE”,referencedColumnName=“someCode”),
@JoinColumn(name=“PARENT\u DATE”,referencedColumnName=“someDate”)
})
父母;
@Id字符串值;
...
}
公共类ChildId实现可序列化{
ParentId parent;//匹配属性的名称和父Id类的类型
字符串值;
}

JPA 2.1规范第2.4.1节讨论了派生标识。

您可以使用
@IdClass
@EmbeddedId
。无论哪种方式,您都在使用“派生标识”。以下是使用
@IdClass
的可能解决方案:

@Entity
@IdClass(ParentId.class)
public class Parent {
    @Id int someId;
    @Id int someCode;
    @Id Date someDate;

    @OneToMany(fetch = FetchType.EAGER, mappedBy = "parent")
    List<Child> children;
}

public class ParentId implements Serializable {
    int someId;
    int someCode;
    Date someDate;
    ...
}

@Entity
@IdClass(ChildId.class)
public class Child {
    @Id
    @ManyToOne
    @JoinColumns({
        @JoinColumn(name="PARENT_ID", referencedColumnName="someId"),
        @JoinColumn(name="PARENT_CODE", referencedColumnName="someCode"),
        @JoinColumn(name="PARENT_DATE", referencedColumnName="someDate") 
    })
    Parent parent;
    @Id String childValue;
    ...
}

public class ChildId implements Serializable {
    ParentId parent; // matches name of attribute and type of Parent Id class
    String childValue;
}
@实体
@IdClass(ParentId.class)
公共类父类{
@Id-int-someId;
@Id-int-someCode;
@Id日期someDate;
@OneToMany(fetch=FetchType.EAGER,mappedBy=“parent”)
列出儿童名单;
}
公共类ParentId实现可序列化{
内体;
int-someCode;
约会某天;
...
}
@实体
@IdClass(ChildId.class)
公营儿童{
@身份证
@许多酮
@连接柱({
@JoinColumn(name=“PARENT\u ID”,referencedColumnName=“someId”),
@JoinColumn(name=“PARENT\u CODE”,referencedColumnName=“someCode”),
@JoinColumn(name=“PARENT\u DATE”,referencedColumnName=“someDate”)
})
父母;
@Id字符串值;
...
}
公共类ChildId实现可序列化{
ParentId parent;//匹配属性的名称和父Id类的类型
字符串值;
}

JPA 2.1规范第2.4.1节讨论了派生身份。

您可以继续使用
@IdClass
单向映射。为此,您可以在
父类
列表子项
字段中添加
@JoinColumns({…}
以及
级联
属性,如下所示:

@Entity @IdClass(ParentId.class)
class Parent {
    @Id int someId;
    @Id int someCode;
    @Id Date someDate;

    @OneToMany(fetch = FetchType.EAGER, cascade=CascadeType.ALL)
    @JoinColumns({
        @JoinColumn(name="someId", referencedColumnName="someId"),
        @JoinColumn(name="someCode", referencedColumnName="someCode"),
        @JoinColumn(name="someDate", referencedColumnName="someDate") 
})    
    List<CKChild> children = new ArrayList<>();
}
class ParentId implements Serializable {
    int someId;
    int someCode;
    Date someDate;
}

@Entity @IdClass(ChildId.class)
class Child {
    @Id int someId;
    @Id int someCode;
    @Id Date someDate;
    @Id String childValue;
}

class ChildId implements Serializable {
    int someId;
    int someCode;
    Date someDate;
    String childValue;
}
并给了我以下信息

Hibernate: select ckparent0_.someCode as someCode1_1_, ckparent0_.someDate as someDate2_1_, ckparent0_.someId as someId3_1_ from Parent ckparent0_
Hibernate: select children0_.someCode as someCode2_0_0_, children0_.someDate as someDate3_0_0_, children0_.someId as someId4_0_0_, children0_.childValue as childVal1_0_0_, children0_.childValue as childVal1_0_1_, children0_.someCode as someCode2_0_1_, children0_.someDate as someDate3_0_1_, children0_.someId as someId4_0_1_ from Child children0_ where children0_.someCode=? and children0_.someDate=? and children0_.someId=?
Hibernate: select children0_.someCode as someCode2_0_0_, children0_.someDate as someDate3_0_0_, children0_.someId as someId4_0_0_, children0_.childValue as childVal1_0_0_, children0_.childValue as childVal1_0_1_, children0_.someCode as someCode2_0_1_, children0_.someDate as someDate3_0_1_, children0_.someId as someId4_0_1_ from Child children0_ where children0_.someCode=? and children0_.someDate=? and children0_.someId=?
**Retrieved :** [org.hibernate.bugs.Parent@1e17ad20, org.hibernate.bugs.Parent@7111ca49]
使用以下DDL

Hibernate: create table Child (childValue varchar(255) not null, someCode integer not null, someDate timestamp not null, someId integer not null, primary key (childValue, someCode, someDate, someId))
Hibernate: create table Parent (someCode integer not null, someDate timestamp not null, someId integer not null, primary key (someCode, someDate, someId))
Hibernate: alter table Child add constraint FKl06s6kkl5xx2s82tlbsh160vo foreign key (someCode, someDate, someId) references Parent

您可以使用单向映射继续使用
@IdClass
。为此,您可以在
父类
列表子项
字段中添加
@JoinColumns({…}
以及
级联
属性,如下所示:

@Entity @IdClass(ParentId.class)
class Parent {
    @Id int someId;
    @Id int someCode;
    @Id Date someDate;

    @OneToMany(fetch = FetchType.EAGER, cascade=CascadeType.ALL)
    @JoinColumns({
        @JoinColumn(name="someId", referencedColumnName="someId"),
        @JoinColumn(name="someCode", referencedColumnName="someCode"),
        @JoinColumn(name="someDate", referencedColumnName="someDate") 
})    
    List<CKChild> children = new ArrayList<>();
}
class ParentId implements Serializable {
    int someId;
    int someCode;
    Date someDate;
}

@Entity @IdClass(ChildId.class)
class Child {
    @Id int someId;
    @Id int someCode;
    @Id Date someDate;
    @Id String childValue;
}

class ChildId implements Serializable {
    int someId;
    int someCode;
    Date someDate;
    String childValue;
}
并给了我以下信息

Hibernate: select ckparent0_.someCode as someCode1_1_, ckparent0_.someDate as someDate2_1_, ckparent0_.someId as someId3_1_ from Parent ckparent0_
Hibernate: select children0_.someCode as someCode2_0_0_, children0_.someDate as someDate3_0_0_, children0_.someId as someId4_0_0_, children0_.childValue as childVal1_0_0_, children0_.childValue as childVal1_0_1_, children0_.someCode as someCode2_0_1_, children0_.someDate as someDate3_0_1_, children0_.someId as someId4_0_1_ from Child children0_ where children0_.someCode=? and children0_.someDate=? and children0_.someId=?
Hibernate: select children0_.someCode as someCode2_0_0_, children0_.someDate as someDate3_0_0_, children0_.someId as someId4_0_0_, children0_.childValue as childVal1_0_0_, children0_.childValue as childVal1_0_1_, children0_.someCode as someCode2_0_1_, children0_.someDate as someDate3_0_1_, children0_.someId as someId4_0_1_ from Child children0_ where children0_.someCode=? and children0_.someDate=? and children0_.someId=?
**Retrieved :** [org.hibernate.bugs.Parent@1e17ad20, org.hibernate.bugs.Parent@7111ca49]
使用以下DDL

Hibernate: create table Child (childValue varchar(255) not null, someCode integer not null, someDate timestamp not null, someId integer not null, primary key (childValue, someCode, someDate, someId))
Hibernate: create table Parent (someCode integer not null, someDate timestamp not null, someId integer not null, primary key (someCode, someDate, someId))
Hibernate: alter table Child add constraint FKl06s6kkl5xx2s82tlbsh160vo foreign key (someCode, someDate, someId) references Parent

首先,这是Groovy,上面的代码有点暗示,但我没有明确提到。这要求注释使用括号“[]”而不是大括号“{}”来指定数组属性,如@JoinColumn

除此之外,这比我想象的要简单。对于具有相同字段的单向关系,我不需要指定实际的列名或引用的列名。只是常见的字段名

我还切换到一个集合,并将@JoinColumns按在数据库中指定键的顺序放置。不过,最后两件事可能并不重要

@Entity @IdClass(ParentId.class)
class Parent {
    @Id int someCode
    @Id Date someDate
    @Id int someId

    @OneToMany(fetch = FetchType.EAGER)
    @JoinColumns([@JoinColumn(name = "someCode"),
        @JoinColumn(name = "someDate"),
        @JoinColumn(name = "someId")])
    Set<Child> children
}
@Entity@IdClass(ParentId.class)
班级家长{
@Id int someCode
@身份证日期
@Id int someId
@OneToMany(fetch=FetchType.EAGER)
@JoinColumns([@JoinColumn(name=“someCode”),
@JoinColumn(name=“someDate”),
@JoinColumn(name=“someId”)])
安排孩子
}

首先,这是Groovy,上面的代码有点暗示了这一点,但我没有明确提到。这要求注释使用括号“[]”而不是大括号“{}”来指定数组属性,如@JoinColumn

除此之外,这比我想象的要简单。对于具有相同字段的单向关系,我不需要指定实际的列名或引用的列名。只是常见的字段名

我还切换到一个集合,并将@JoinColumns按在数据库中指定键的顺序放置。不过,最后两件事可能并不重要

@Entity @IdClass(ParentId.class)
class Parent {
    @Id int someCode
    @Id Date someDate
    @Id int someId

    @OneToMany(fetch = FetchType.EAGER)
    @JoinColumns([@JoinColumn(name = "someCode"),
        @JoinColumn(name = "someDate"),
        @JoinColumn(name = "someId")])
    Set<Child> children
}
@Entity@IdClass(ParentId.class)
班级家长{
@Id int someCode
@身份证日期
@Id int someId
@在