【问题标题】:Hibernate Mapping - connecting table with no @IdHibernate Mapping - 没有@Id的连接表
【发布时间】:2014-11-19 10:36:06
【问题描述】:

我有三张桌子,MemberAddressMem_AddrMemberAddress 实体由 Mem_Addr 表映射/连接。多对多。

对于MemberAddress,我有以下实体:

@Entity 
@Table (name="Member")
public class Member{

    @Id  //....
    private Integer mem_id;

    @OneToOne
    @JoinTable     (name = "Mem_Addr", 
             joinColumns = @JoinColumn(name = "addr_id"), 
      inverseJoinColumns = @JoinColumn(name = "mem_id"))
    Set<Address> addresses = new HashSet<Address>;
    ...
}

Mem_Addr 表(没有关联实体)。

addr_id // (PK) Sequence
mem_id  // (FK to mem_id in Member table) 
....
....

Address实体。

@Entity
@Table(name="Address")
public class Address {

   private String addr_id; // Foreign Key to addr_id in Mem_addr table
   private String address1;
   ...
}

我在Address 表/实体中没有 ID。 (请不要问我关于设计的问题。它现在无法更改。)

所以当我加载成员时,我想加载该成员的所有地址位置。

解决办法是什么?

编辑:更多信息...

基本上一些Members 将在Mem_Addr 表中有一个新条目。对于Mem_addr 表中的每个条目,Address 表中都会有一个条目。

要获取成员的地址,我需要参考 Mem_Addr。 Mem_Addr 以addr_id 作为主键,Address 以addr_id 作为外键。

【问题讨论】:

  • 地址实体中是否有 addr_id,因为我在 Mem 实体中看到您正在调用它?
  • @Rika 你是对的.. 我打错了。已更正。
  • 我认为您可能可以在没有 Id 的情况下进行连接,但它必须具有 Embeddable 注释,请参阅此处stackoverflow.com/questions/767277/hibernate-and-no-pk
  • @Rika:如果您尝试映射的表是其他东西的外键,我认为@Embeddable 方法将不起作用。一个 Hibernate 实体应该是一个独立的、独立的东西,所以 Hibernate 会尝试在Address 中插入一个新行,这会由于未满足 FK 约束而失败并被回滚。
  • @Tim 如果他把 Mem_Addr 变成一个实体,然后把 String addr_id 变成一个实体,它可能会起作用;在地址到 MemAddr addr_id;然后做 Embeddable 的事情,它应该用级联正确插入它

标签: java oracle hibernate entity hibernate-onetomany


【解决方案1】:

您确定Mem_Addr 表是多对多的,而不是一对多的吗?我看不出一个Address 怎么可能与多个Member 相关联...

假设它实际上是一对多的,通过@SecondaryTable 注释将您的Address 实体映射到Mem_AddrAddress 表,如Hibernate Mapping Two Tables to One Class 中所述,将id 映射到Mem_Addr.addr_idMember 通过Mem_Addr.mem_id,其他所有内容通过Address 中的其他字段。

我还没有这样做,但我相信它会起作用:

@Entity
@Table(name = "Address")
@SecondaryTable(name = "Mem_Addr", pkJoinColumns={
    @PrimaryKeyJoinColumn(name="addr_id" referencedColumnName="addr_id")
})
class Address {
    @Id
    @Column
    private String addr_id;

    ....
}

【讨论】:

  • 有可能。因为在保险领域,多个客户可以在同一个地址。好的,如果我假设它将是@OneToMany,但您的解决方案尚不清楚。你能详细说明一下吗?
  • 我没有这样做(谢天谢地,我总是有比你坚持的更合理的模式),但你应该能够为此使用 @SecondaryTable 注释,因为在stackoverflow.com/questions/1667918/…中描述。
  • 另外,我同意在现实世界中,一个Address 可以有多个Members。但是我不相信在您的数据库模式中这是可能的(您必须为每个 Member 对象创建一个 Address 对象,即使该 Address 的值相同),这就是为什么希望您将被允许在将来的某个时候更改该架构。
  • 好的。我正在用更多的洞察力更新我的问题。我想它可能会产生与您不同的解决方案。 :-)。
  • 您添加的任何内容都不会更改此处的解决方案。因为主键在Mem_Addr 表中,所以Address 类必须映射到它,但它也需要映射到Address 表。要将单个类映射到两个表,您需要按照我的建议使用 @SecondaryTable。
【解决方案2】:

好的,因为插入和更新不是必需的,以下(理论上)应该可以工作:

@Entity
@Table(name = "Address")
class Address {

 @Id
 private AddressKey id;

 public void setId(AddressKey id) {
 this.id = id;
 }

 public void getId() {
 return id;
 }
}

@Embeddable
class AddressKey implements Serializable {
   @Column(name = "addr_id")
   private String addrId; //also the underscore should be deleted

   @Column(name = "address_1")
   private String address1;



  }

这是为没有主键的表找到的解决方法。正如你所看到的,它几乎是一个假身份证。

【讨论】:

  • 如果我们不担心插入和更新,那么为什么还要使用@Embeddable?只需将addr_id 映射为@Id 即可。 (此外,address1 不是表主键的一部分,所以我不确定你为什么将它包含在 @Embeddable...)
  • 但是如何将地址映射到成员表。这两者之间没有联系。这可能是一件简单的事情.. .. 你明白我.. 我是 Hibernate 的新手 :-)
  • 尽管如此,我认为故意映射一个不能用于写入数据库的 Hibernate 实体是一个错误的决定,即使您认为您不需要该功能。很可能您会在某个时候使用它们,即使您在生产中真的不需要它们,如果您想将一些测试数据写入虚拟数据库以用于单元测试怎么办?我认为,当其他方法也可以工作并且没有这些缺点时,采用这种方法将是一个错误,但我们都可以做出自己的选择,所以这是你的决定。
  • @Tim,这很好。可能我需要允许插入和更新。我会同意的。
【解决方案3】:

不幸的是,没有办法,Hibernate 要求您的表具有主键。

您可以查看this document

【讨论】:

    猜你喜欢
    • 2014-11-20
    • 2014-09-30
    • 2016-10-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-07
    • 1970-01-01
    相关资源
    最近更新 更多