我这里有一个数据库 PERSON
-ADDRESS
-ADDRESS_TYPE
由三重联接表维护的关系 PERSON_ADDRESS
。 PERSON
-ADDRESS
关系实际上是一对多。
PERSON
ID FIRSTNAME LASTNAME -- --------- -------- 1 John Doe 2 Jane Doe
ADDRESS
ID STREET CITY -- -------------------- ------------- 1 Home Street 1 Hometown 2 Office Street 1 Officetown 3 Main Street 1 Maintown 4 Business Building 1 Businesstown
ADDRESS_TYPE
ID NAME -- --------------- 1 Home Address 2 Office Address
PERSON_ADDRESS
PERSON_ID ADDRESS_TYPE_ID ADDRESS_ID --------- --------------- ---------- 1 1 1 1 2 2 2 1 3 2 2 4
For practical reasons, I'd like to have my Person
entity to end up like:
public class Person {
private Address homeAddress; // Insertable/updateable by ADDRESS_TYPE_ID=1
private Address officeAddress; // Insertable/updateable by ADDRESS_TYPE_ID=2
}
这可以通过 JPA 2.0 注释实现吗?
我已阅读Map Key Columns chapter of the JPA wikibook看来我必须使用 @MapKeyJoinColumn
,但我并不完全清楚如何在这种情况下成功使用它。我预计会看到 @JoinColumn
示例,但它在 wikibook 的代码片段中不存在。
如果 @MapKeyJoinColumn
无法做到这一点,然后在 @MapKeyClass
的帮助下另一种方法在Map<AddressType, Address>
上也欢迎,只要我最终能得到 getHomeAddress()
和getOfficeAddress()
在 Person
实体。
最佳答案
假设您有两个预定义的 AddressType
(当可以添加其他类型时),则以下使用 @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);
}
}
因此,当可以通过直接访问 map 来使用其他类型时,您可以为预定义地址类型提供预定义方法。 orphanRemoval
用于实现 setHomeAddress(null)
行为。 @ElementCollection
在这里不起作用,因为它不支持连接表。
关于jpa - 通过三重联接表在每个 AddressType 的 Person 中定义多个 Address 属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3850967/