La définition de plusieurs propriétés en personne par adresse AddressType par une triple table de jointure

StackOverflow https://stackoverflow.com/questions/3850967

  •  27-09-2019
  •  | 
  •  

Question

Je l'ai ici une base de données avec un PERSON - ADDRESS - relation ADDRESS_TYPE maintenue par une triple table de jointure PERSON_ADDRESS. La relation PERSON-ADDRESS est effectivement l'un à plusieurs.

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

Pour des raisons pratiques, j'aimerais avoir mon entité Person finir comme:

public class Person {
    private Address homeAddress; // Insertable/updateable by ADDRESS_TYPE_ID=1
    private Address officeAddress; // Insertable/updateable by ADDRESS_TYPE_ID=2
}

Est-ce toujours possible avec annotations JPA 2.0?

J'ai lu Carte Colonnes clés chapitre de l'Assemblée parlementaire paritaire wikilivre et il semble que je dois utiliser un @MapKeyJoinColumn , mais il est pas tout à fait clair pour moi comment utiliser avec succès dans cette situation. Je pensais voir un exemple @JoinColumn le long, mais il est absent dans les extraits de code dans le wikilivre.

Si cela est impossible avec @MapKeyJoinColumn, puis une autre approche avec l'aide de peut-être @MapKeyClass sur Map<AddressType, Address> est également la bienvenue, aussi longtemps que je peux retrouver avec un getHomeAddress() et getOfficeAddress() dans l'entité Person.

Était-ce utile?

La solution

En supposant que vous avez deux AddressTypes prédéfinis quand d'autres peuvent être ajoutés, l'approche suivante avec @MapKeyJoinColumn fonctionne:

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);
    }
}

Ainsi, vous avez des méthodes prédéfinies pour les types d'adresses prédéfinies, alors que d'autres types peuvent être utilisés par un accès direct à la carte. orphanRemoval est utilisé pour mettre en œuvre le comportement de setHomeAddress(null). @ElementCollection ne fonctionnerait pas ici car il ne supporte pas se joindre à la table.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top