2014-09-24 123 views
1

我有三个表,Member,AddressMem_AddrMemberAddress实体通过Mem_Addr表映射/连接。多对多。休眠映射 - 连接表没有@Id

我为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。 (请不要问我关于这个设计的问题,它现在不可改变。)

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

解决方案是什么?

编辑:更多信息...

基本上一些Member旨意在Mem_Addr表中的新条目。对于Mem_addr表中的每个条目,将在Address表中有条目。

要获取成员的地址,我需要引用Mem_Addr。 Mem_Addr具有addr_id作为主键,地址具有addr_id作为外键。

+1

Address实体中是否存在addr_id,因为我在Mem实体中看到您正在调用它? – Rika 2014-09-24 20:03:13

+0

@Rika你是对的..我打错了。纠正。 – 2014-09-24 20:05:31

+0

我想你可能可以连接没有Ids,但它必须有Embeddable注释,请看这里http://stackoverflow.com/questions/767277/hibernate-and-no-pk – Rika 2014-09-24 20:13:42

回答

1

不幸的是,没有办法,Hibernate需要你的表有主键。您可以检出this document

1

您确定Mem_Addr表是多对多的,而不是一对多吗?我看不出一个Address可以用一个以上的Member相关...

假设它实际上是一个对许多人来说,映射你的Address实体既通过@SecondaryTable注释的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; 

    .... 
} 
+0

其可能性。因为在保险领域,多个客户可以在同一地址。好吧,如果我假设它将成为@OneToMany,但你的解决方案并不明确。你能详细说明吗? – 2014-09-24 20:30:41

+0

我还没有这样做(幸好我总是拥有比你坚持的更合理的模式),但是你应该可以使用@SecondaryTable注解来实现这一点,如http:// stackoverflow的.com /问题/ 1667918 /休眠映射-两表对一类。 – Tim 2014-09-24 20:43:41

+0

另外,我同意在现实世界中,可能有多个“成员”用于单个“地址”。但我不相信在你的数据库模式中是可能的(即使这个“Address”的值是相同的,你也必须为每个Member对象创建一个Address对象),这就是为什么希望您将被允许在将来的某个时刻更改该架构。 – Tim 2014-09-24 20:46:43

1

好吧,因为插入和更新是没有必要的,下面的(理论上)或许应该工作:

@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; 



    } 

这是发现那些没有主键的表一个解决方法。正如你所看到的,它几乎使一个虚假的Id。

+0

如果我们不担心插入和更新,那么为什么要打扰@Embeddable?只需将'addr_id'映射为@Id并完成它。 (此外,'address1'不是表的主键的一部分,所以我不确定为什么你将它包含在@Embeddable ...) – Tim 2014-09-24 21:35:50

+0

但是,如何将地址映射到成员表。这两者之间没有联系。这可能是一个简单的事情.. ..你让我..我是一个新手Hibernate :-) – 2014-09-24 21:36:46

+1

虽然,我认为这是一个坏的决定,故意映射一个不能用于Hibernate实体写入数据库,即使你认为你不需要这种能力。在某些情况下,你可能会有这种可能性,即使你真的从不在生产中需要它们,如果你想将一些测试数据写入虚拟数据库以便在单元测试中使用,该怎么办?我认为采用这种方法在其他方法也可行时不会出现这些缺点,但我们都会做出自己的选择,这是您的呼叫。 – Tim 2014-09-24 21:38:55