13

我在这里有一个由三联表维护的具有--关系的PERSON数据库ADDRESS。-关系实际上是一对多的。ADDRESS_TYPEPERSON_ADDRESSPERSONADDRESS

PERSON

ID 名字 姓氏
-- --------- --------
1 约翰·多伊
2简·多伊

ADDRESS

ID 街市
-- ---------- -------------
1 家乡街 1 家乡
2 办公街 1 办公城
3 主街 1 主城
4 商业大厦 1 商业城

ADDRESS_TYPE

身份证名称
-- --------------
1 个家庭住址
2 办公地址

PERSON_ADDRESS

PERSON_ID ADDRESS_TYPE_ID ADDRESS_ID
--------- --------------- ----------
1 1 1
1 2 2
2 1 3
2 2 4

出于实际原因,我希望我的Person实体最终如下:

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 注释是否有可能实现这一点?

我已经阅读了JPA wikibook 的 Map Key Columns 章节,似乎我必须使用 a @MapKeyJoinColumn,但我并不完全清楚如何在这种情况下成功使用它。我希望看到一个@JoinColumn示例,但在 wikibook 的代码片段中没有它。

如果用 不可能做到这一点,那么也欢迎使用可能在 a@MapKeyJoinColumn的帮助下的替代方法,只要我可以在实体中得到 a和。@MapKeyClassMap<AddressType, Address>getHomeAddress()getOfficeAddress()Person

4

1 回答 1

12

假设您有两个AddressType可以添加其他的预定义 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);
    }
}

因此,您已经为预定义的地址类型预定义了方法,而其他类型可以通过直接访问地图来使用。orphanRemoval用于实现setHomeAddress(null)行为。@ElementCollection在这里不起作用,因为它不支持连接表。

于 2010-10-03T19:51:16.477 回答