13

トリプル結合テーブルによって維持されるリレーションシップをPERSON持つデータベースがここにあります。-関係は事実上 1対多です。ADDRESSADDRESS_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 の章を読みましたが、を使用する必要があるようですが@MapKeyJoinColumn、この状況でそれをうまく使用する方法が完全にはわかりません。それに沿った例を期待して@JoinColumnいましたが、wikibook のコード スニペットにはありません。

でそれが不可能な場合は、エンティティ内でandで終わることができる限り、多分on a の@MapKeyJoinColumn助けを借りた代替アプローチも歓迎します。@MapKeyClassMap<AddressType, Address>getHomeAddress()getOfficeAddress()Person

4

1 に答える 1

12

AddressTypeother を追加できるときに2 つの定義済み があると仮定すると、次のアプローチが@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 に答える