【问题标题】:JPA: how to use @ElementCollection annotation?JPA:如何使用@ElementCollection 注解?
【发布时间】:2013-08-23 15:25:53
【问题描述】:

我需要你的帮助来映射 Hibernate 中两个表的关系,使用 @ElementCollection 注释。

第一个是父表
表名:
数据库列

KEY1         Char      (first primary key field)
KEY2         Char      (second primary key field)
DESCRIPTION  Char
DEPENDENTID  BigInt

第二个是依赖表
表名:依赖
数据库列

PARENTID     BigInt    (first primary key field)
CODE         Char      (second primary key field)
FIELD1       Char
FIELD2       Char

我需要使用@EmbeddedId 注释为两个表定义PK, 所以我创建了两个类:

@Embeddable
public class ParentPK implements Serializable
{
   @Column(name="K1")
   private String iK1;
   @Column(name="K2")
   private String iK2;
  // I omit the constructor, getter, setter, equals, hashcode method 
}

@Embeddable
public class DependentPK implements Serializable
{
  @Column(name="PARENTID")
  private String iParentId;
  @Column(name="CODE")
  private String iCode;
  // I omit the constructor, getter, setter, equals, hashcode method 
}

然后我创建了两个 bean:
DEPENDENT 表的类。
请注意,在这个类中我不想有任何关系注释

@Entity
@Table(name = "DEPENDENT")
public class DependentBean implements Serializable
{
   @EmbeddedId
   private DependentPK iDependentPK;
   @Column(name = "FIELD1")
   private String iField1;
   @Column(name = "FIELD2")
   private String iField2;
   // I omit the constructor, getter, setter methods
}

还有 PARENT 表的类

@Entity
@Table(name = "PARENT")
public class ParentBean implements Serializable
{
   @EmbeddedId
   ParentPK iParentPK;
   @Column(name = "DESCRIPTION")
   private String iDescription;
   @Column(name = "DEPENDENTID")
   private long iDependentId;
   @ElementCollection
   @CollectionTable(name="DEPENDENT", joinColumns={@JoinColumn(name="PARENTID",  referencedColumnName="DEPENDENTID")})
   private Set<DependentBean> iDependentBeans = new HashSet<DependentBean>();
   // I omit the constructor, getter, setter methods
}

当我尝试部署时出现错误:

原因:org.hibernate.MappingException:外键 (FK9619C2A17B05CB2:依赖 [iDependentBeans_PARENTID,iDependentBeans_CODE])) 必须相同 作为引用的主键的列数(DEPENDENT [PARENTID,iDependentBeans_PARENTID,iDependentBeans_CODE])

所以我做错了什么,但我无法想象是什么。 有人愿意帮助我吗?

【问题讨论】:

    标签: java sql hibernate jpa


    【解决方案1】:

    @ElementCollection 应与基本类型或可嵌入类一起使用,而不是用于实体。

    DependentBean 是一个实体。

    尝试使用一对多映射并修改您的架构

    父架构

    KEY1         Char      (PK)
    KEY2         Char      (PK)
    DEPENDENTID  BigInt    (PK)
    DESCRIPTION  Char
    

    依赖模式

    CODE         Char      (PK)
    PARENTID     BigInt    (FK)
    KEY1         Char      (FK)
    KEY2         Char      (FK)
    FIELD1       Char
    FIELD2       Char
    

    一对多映射

    父PK

    @Embeddable
    public class ParentPK {
        @Column(name = "K1")
        private String iK1;
        @Column(name = "K2")
        private String iK2;
        @Column(name = "DEPENDENTID")
        private long iDependentId;
    }
    

    父豆

    @Entity
    @Table(name = "PARENT")
    public class ParentBean {
        @EmbeddedId
        ParentPK iParentPK;
    
        @OneToMany(mappedBy = "parent")
        List<DependentBean> iDependentBeans;
    }
    

    依赖豆

    @Entity
    @Table(name = "DEPENDENT")
    public class DependentBean {
        @Id
        @Column(name = "CODE")
        private String iCode;
    
        @ManyToOne
        @JoinColumns({ 
          @JoinColumn(name = "PARENTID", referencedColumnName = "iDependentId"),  
          @JoinColumn(name = "K1", referencedColumnName = "iK1"),
          @JoinColumn(name = "K2", referencedColumnName = "iK2") })
        ParentBean parent;
    }
    

    【讨论】:

    • 首先感谢您的回答。但是我已经看到,当访问父表时,使用 onetomany 注释 Hibernate 进行连接。只有在访问依赖表的属性时,我才需要访问依赖表。那么,这样做的方法是什么?
    • 我认为您使用@O​​neToMany(fetch = FetchType.EAGER),这肯定会像您所说的那样进行连接。尝试使用 @OneToMany(fetch = FetchType.LAZY) 并确保在关闭会话之前访问该属性。否则,你会得到一个 LazyInitializationException。
    • 您好,但是可以在我的两个表 ParentDependent 之间定义 OneToMany 吗?如您所见,Parent 表具有字段“DEPENDENTID”,该字段可能链接到 Dependent 表的“PARENTID”字段。 从属表有另一个主键字段:'CODE'。这两个表具有使用可嵌入类描述的自己的主键。那么,在您看来,可以在这种情况下使用 @OneToMany 注释吗?我尝试了几种方法都没有成功,并且我尝试了很多搜索却一无所获。提前感谢您的宝贵时间
    • 嗨@user2711522,您的情况不是一对多映射。唯一可能的解决方案是将父表的复合键(ID,DEPENDENTID)作为从属表的复合外键。
    • 嗨@study,感谢您的回答。如果我理解得很好:我需要更改我的从属表结构以放置父表主键,然后使用这些字段在我的从属表中有一个外键来引用父表。这将成为 Dependent 表和 Parent 表之间的 ManyToOne,并且 ManyToOne 关系将在 Dependent pojo 中定义。它是否正确?但如果是这样,我的父母 pojo 中没有 Dependent pojos 的集合。还是我错了?
    猜你喜欢
    • 2016-11-18
    • 2017-05-22
    • 2011-04-12
    • 1970-01-01
    • 2013-01-21
    • 2011-06-25
    • 1970-01-01
    • 1970-01-01
    • 2020-07-04
    相关资源
    最近更新 更多