Jpa 通过三重联接表为每个AddressType定义多个个人地址属性
我这里有一个数据库,它有一个Jpa 通过三重联接表为每个AddressType定义多个个人地址属性,jpa,map,jpa-2.0,jointable,Jpa,Map,Jpa 2.0,Jointable,我这里有一个数据库,它有一个个人-地址-地址类型关系,由一个三重连接表个人地址维护。人-地址关系实际上是一对多关系 PERSON ID FIRSTNAME LASTNAME -- --------- -------- 1 John Doe 2 Jane Doe 地址类型 ID NAME -- --------------- 1 Home Address 2 Office Address 出于实际原因,我希望我的个人实体的结局如下: public class Perso
个人
-地址
-地址类型
关系,由一个三重连接表个人地址
维护。人
-地址
关系实际上是一对多关系
PERSON
ID FIRSTNAME LASTNAME
-- --------- --------
1 John Doe
2 Jane Doe
地址类型
ID NAME
-- ---------------
1 Home Address
2 Office Address
出于实际原因,我希望我的个人
实体的结局如下:
public class Person {
private Address homeAddress; // Insertable/updateable by ADDRESS_TYPE_ID=1
private Address officeAddress; // Insertable/updateable by ADDRESS_TYPE_ID=2
}
JPA2.0注释是否可能实现这一点
我已经阅读了,似乎我必须使用,但我不完全清楚如何在这种情况下成功地使用它。我希望看到一个@JoinColumn
示例,但在wikibook的代码片段中没有
如果使用
@MapKeyJoinColumn
无法实现这一点,那么也可以使用另一种方法,借助于映射
,只要我可以在个人
实体中使用getHomeAddress()
和getOfficeAddress()
假设您有两个预定义的地址类型
s,而其他地址类型可以添加,那么使用@MapKeyJoinColumn
的以下方法有效:
public class AddressType {
public static final AddressType HOME = new AddressType(1L, "Home");
public static final AddressType OFFICE = new AddressType(2L, "Office");
...
... hashCode, equals based on id ...
}
public class Person {
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
@JoinTable(name = "PERSON_ADDRESS",
joinColumns = @JoinColumn(name = "PERSON_ID"),
inverseJoinColumns = @JoinColumn(name = "ADDRESS_ID"))
@MapKeyJoinColumn(name = "ADDRESS_TYPE_ID")
private Map<AddressType, Address> addresses = new HashMap<AddressType, Address>();
...
public Address getHomeAddress() {
return getAddress(AddressType.HOME);
}
public void setHomeAddress(Address a) {
setAddress(AddressType.HOME, a);
}
...
public void setAddress(AddressType type, Address a) {
if (a == null) {
addresses.remove(type);
} else {
addresses.put(type, a);
}
}
public Address getAddress(AddressType type) {
return addresses.get(type);
}
}
公共类地址类型{
公共静态最终地址类型HOME=新地址类型(1L,“HOME”);
公共静态最终地址类型OFFICE=新地址类型(2L,“OFFICE”);
...
…哈希代码,基于id的等于。。。
}
公共阶层人士{
@OneToMany(cascade=CascadeType.ALL,orphan=true)
@JoinTable(name=“PERSON\u ADDRESS”,
joinColumns=@JoinColumn(name=“PERSON\u ID”),
inverseJoinColumns=@JoinColumn(name=“ADDRESS\u ID”))
@MapKeyJoinColumn(name=“地址\类型\ ID”)
私有映射地址=新HashMap();
...
公共地址getHomeAddress(){
返回getAddress(AddressType.HOME);
}
公共无效设置家庭地址(地址a){
setAddress(AddressType.HOME,a);
}
...
公共无效设置地址(地址类型,地址a){
如果(a==null){
地址。删除(类型);
}否则{
地址。put(类型,a);
}
}
公共地址getAddress(AddressType类型){
返回地址。获取(类型);
}
}
因此,当其他类型可以通过直接访问地图来使用时,您可以为预定义的地址类型使用预定义的方法<代码>删除用于实现
设置家庭地址(null)
行为@ElementCollection
在这里不起作用,因为它不支持联接表。您是否对地址类型使用枚举?因为这是有道理的,因为您需要编译时固定地址类型。@Bozho:我还没有完全实现它,但如果可能的话,使用@Enumerated
肯定是我的首选,是的。啊哈。你的持久性提供者是什么?(我想,作为最后的手段,可以使用特定于提供者的注释)@Bozho:我不希望依赖于提供者,但它是Glassfish 3.0.1附带的Eclipselink 2.0.1。@BalusC:不清楚的是人
-地址
一对多或多对多。哦,它能工作:)非常感谢。与此同时,我也在摆弄,但我的@JoinTable
完全错了。现在这也更有意义了。然而,我很好奇是否可以使用enum AddressType
@BalusC:我认为除非更改数据库模式,否则不能使用enum
。您可以使用enum
或映射到ADDRESS\u TYPE
表的实体。我无法控制DB架构。无论如何,谢谢你:)
public class Person {
private Address homeAddress; // Insertable/updateable by ADDRESS_TYPE_ID=1
private Address officeAddress; // Insertable/updateable by ADDRESS_TYPE_ID=2
}
public class AddressType {
public static final AddressType HOME = new AddressType(1L, "Home");
public static final AddressType OFFICE = new AddressType(2L, "Office");
...
... hashCode, equals based on id ...
}
public class Person {
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
@JoinTable(name = "PERSON_ADDRESS",
joinColumns = @JoinColumn(name = "PERSON_ID"),
inverseJoinColumns = @JoinColumn(name = "ADDRESS_ID"))
@MapKeyJoinColumn(name = "ADDRESS_TYPE_ID")
private Map<AddressType, Address> addresses = new HashMap<AddressType, Address>();
...
public Address getHomeAddress() {
return getAddress(AddressType.HOME);
}
public void setHomeAddress(Address a) {
setAddress(AddressType.HOME, a);
}
...
public void setAddress(AddressType type, Address a) {
if (a == null) {
addresses.remove(type);
} else {
addresses.put(type, a);
}
}
public Address getAddress(AddressType type) {
return addresses.get(type);
}
}