web-dev-qa-db-fra.com

Exception de mappages inscriptibles multiples dans EclipseLink

J'ai ces tableaux:

tables

Quelle est mon intention: un utilisateur peut être un company ou un person mais chacun d'eux a quelque chose en commun, comme nom d'utilisateur qui est le email et password, j'ai donc utilisé les outils JPA pour générer les entités de la table qui en résultent:

public class User implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    private int id;

    private String email;

    private String password;

    private int reputation;

    //bi-directional one-to-one association to Company
    @OneToOne(mappedBy="user", cascade={CascadeType.ALL})
    private Company company;

    //bi-directional many-to-one association to Location
    @OneToMany(mappedBy="user")
    private List<Location> locations;

    //bi-directional one-to-one association to Person
    @OneToOne(mappedBy="user")
    private Person person;

    //bi-directional many-to-one association to Product
    @OneToMany(mappedBy="user")
    private List<Product> products;

    //bi-directional many-to-one association to UserType
    @ManyToOne
    @JoinColumn(name="type")
    private UserType userType;

    //bi-directional many-to-one association to UserPhone
    @OneToMany(mappedBy="user")
    private List<UserPhone> userPhones;

    //bi-directional many-to-one association to UserPicture
    @OneToMany(mappedBy="user")
    private List<UserPicture> userPictures;

    //bi-directional many-to-one association to UserSocialNetwork
    @OneToMany(mappedBy="user")
    private List<UserSocialNetwork> userSocialNetworks;

        // getter and setters

}

Maintenant, si j'essaie de persister, un objet utilisateur lance l'exception suivante dans EclipseLink:

Exception [EclipseLink-48] (Eclipse Persistence Services - 2.3.0.v20110604-r9504): org.Eclipse.persistence.exceptions.DescriptorException
Exception Description: Multiple writable mappings exist for the field [COMPANY.id_user].  Only one may be defined as writable, all others must be specified read-only.
Mapping: org.Eclipse.persistence.mappings.OneToOneMapping[user]
Descriptor: RelationalDescriptor(entity.Company --> [DatabaseTable(COMPANY)])
Exception [EclipseLink-48] (Eclipse Persistence Services - 2.3.0.v20110604-r9504): org.Eclipse.persistence.exceptions.DescriptorException
Exception Description: Multiple writable mappings exist for the field [PERSON.id_user].  Only one may be defined as writable, all others must be specified read-only.
Mapping: org.Eclipse.persistence.mappings.OneToOneMapping[user]
Descriptor: RelationalDescriptor(entity.Person --> [DatabaseTable(PERSON)])
Runtime Exceptions: 

Le mappage généré est-il incorrect? Comment puis-je résoudre cette exception?

Mise à jour

public class Company implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    @Column(name="id_user")
    private int idUser;

    private String email;

    private String name;

    //bi-directional many-to-one association to Area
    @ManyToOne
    @JoinColumn(name="area")
    private Area areaBean;

    //bi-directional one-to-one association to User
    @OneToOne(cascade={CascadeType.ALL})
    @JoinColumn(name="id_user", insertable=false, updatable=false)
    private User user;

        // getter and setters
}

@Entity
public class Person implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    @Column(name="id_user")
    private int idUser;

    @Temporal( TemporalType.DATE)
    private Date birthdate;

    private String gender;

    private String name;

    private String surname;

    //bi-directional one-to-one association to User
    @OneToOne
    @JoinColumn(name="id_user", insertable=false, updatable=false)
    private User user;

        // getters and setters
}
25
Valter Silva

Pour ce faire, vous devez utiliser @PrimaryKeyJoinColumn au lieu de simplement vieux @JoinColumn.

exemple de référence wiki sur PrimaryKeyJoinColumn

37
klonq

J'ai résolu mon problème en plaçant le insertable=false, updatable=false dans le @JoinColumn annotation dans les deux classes, Person et Company.

35
Valter Silva

Je suppose que vous avez mappé id_user deux fois, une fois en utilisant un mappage @Id de base et une fois en utilisant @ManyToOne. Vous devez en créer un en lecture seule, c'est-à-dire insérable/modifiable = false. Ou mieux, supprimez simplement l'ID de base et placez le @Id sur le @ManyToOne.

Voir, http://en.wikibooks.org/wiki/Java_Persistence/Identity_and_Sequencing#Primary_Keys_through_OneToOne_and_ManyToOne_Relationships

4
James