2013-07-17 89 views
0

我希望我可以清楚地解释这第一次尝试。所以我有两个实体:人员和地址。一个人可以有很多地址,所以我的Person实体由一个地址列表组成。请注意,地址可以在不同的人之间共享,但是我的Address实体不需要对Person实体的引用。此外,每个地址实体将具有排名属性。JPA - @OneToMany与JoinTable

我的表结构如下:

PERSON (
    person_id, 
    etc, 
    primary key (person_id) 
) 

ADDRESS (
    address_id, 
    etc, 
    primary key (address_id) 
) 

PERSON_ADDRESS_MAP (
    person_id, 
    address_id, 
    rank, 
    foreign key (person_id) references person (person_id), 
    foreign key (address_id) references address (address_id), 
    primary key (person_id, address_id, rank) 
) 

鉴于上述情况,我不知道如何注释我的人的地址列表,或在地址秩属性。我怀疑的人将如下所示:

@Entity 
public class Person { 
    @OneToMany(cascade = CascadeType.ALL, fetch=FetchType.EAGER) 
    @JoinTable(name="person_address_map", [email protected](name="person_id"), [email protected](name="address_id")) 
    private List<Address> addresses; 
    ... 
} 

我在如何注释排名在地址实体无能。

在此先感谢

+0

正文说排名在Address中,但在表格描述中说它在PERSON_ADDRESS_MAP中。哪一个是真的? –

+0

两者都是如此。 Rank是Address实体的一个属性,但它存储在连接表中,因为一个人的一个地址可能与另一个人的地址不同。例如,鲍勃将地址'A'作为他的第一个地址,但玛丽(住在同一地址)将她的第二个地址评为'A'。 – user1491636

回答

0

首先,人与地址之间的逻辑关联是多到多,因为一个人有多个地址,住址是由许多人共享。

你说的排名是Address的一个属性。但是对于给定的地址,等级可以是1(对于鲍勃)或2(对于玛丽)。这只是简单地表明(并且表格模型清楚地显示)该等级不是Address的一个属性。

所以,解决问题的方法很简单:你必须在PERSON_ADDRESS_MAP表映射到实体:

public class Person { 
    @OneToMany(mappedBy = "person") 
    private Set<RankedAddress> rankedAddresses; 
} 

public class RankedAddress { 
    @ManyToOne 
    private Person person; 

    @ManyToOne 
    private Address address; 
} 

public class Address { 
    @OneToMany(mappedBy = "adress") 
    private Set<RankedAddress> rankedAddresses; 
} 

我也劝你,为所有实体,增加一个单列,自动生成的ID(和相应的列)到RankingAddress实体。

如果rank是连接表的唯一附加,并且如果它用于包含某个人的地址列表中每个地址的索引(即它从0到N-1,N是一个地址的数目用户),然后有一个选择,不强制你映射连接表的实体:

public class Person { 
    @ManyToMany 
    @OrderColumn(name = "rank") 
    private List<Address> addresses; 
} 

注意,列的值将完全JPA办理,也只会是用于存储列表中给定索引处的每个地址。它不可用于查询,除了通过列表中的索引之外,您无法知道某人的地址等级。

+0

替代方案是我正在寻找的。谢谢! – user1491636