Ответ 1
Предполагая, что у вас есть два предопределенных 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);
}
}
Итак, у вас есть предопределенные методы для предопределенных типов адресов, когда другие типы могут использоваться через прямой доступ к карте. orphanRemoval
используется для реализации поведения setHomeAddress(null)
. @ElementCollection
здесь не работает, потому что он не поддерживает таблицу соединений.