EclipseLink 中的多个可写映射异常

Posted

技术标签:

【中文标题】EclipseLink 中的多个可写映射异常【英文标题】:Multiple writable mappings exception in EclipseLink 【发布时间】:2011-12-18 14:56:34 【问题描述】:

我有这些表:

我的意图是:用户可以是companyperson,但他们每个人都有一些共同点,作为用户名是emailpassword,所以我使用了JPA 工具从表中生成实体:

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


现在,如果我尝试持久化用户对象,则会在 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: 

生成的映射是否错误? 我该如何解决这个异常?

更新

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

【问题讨论】:

【参考方案1】:

我解决了将insertable=false, updatable=false 放在两个类中的@JoinColumn 注释中的问题,PersonCompany

【讨论】:

【参考方案2】:

正确的做法是使用@PrimaryKeyJoinColumn 而不是普通的旧@JoinColumn

reference wiki example on PrimaryKeyJoinColumn

【讨论】:

我有一个表,其中只有一列是另一个表的 id 的子集。这为我解决了。 您好,团队!它帮助我。我的 JSF 应用程序在 Customers(ID) 和 Comments(CUSTID) 表之间使用 ONE to MANY 我将 @JoinColumn(name="ID", referencedColumnName="CUSTID") 切换到 @PrimaryKeyJoinColumn(name="ID", referencedColumnName="CUSTID ")【参考方案3】:

我的猜测是您将 id_user 映射了两次,一次使用基本 @Id 映射,一次使用 @ManyToOne。您需要将其中之一设为只读,即可插入/可更新=假。或者更好的是,只需删除基本 id,然后将 @Id 放在 @ManyToOne 上。

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

【讨论】:

赞成,因为提供了参考。我建议您在回答中也提及“@PrimaryKeyJoinColumn”

以上是关于EclipseLink 中的多个可写映射异常的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 EclipseLink 重新连接丢失的连接?

Eclipselink 实体持续存在问题

JPA 2.1、Eclipselink、SQL Server、Spring - NamedStoredProcedureQuery 结果映射

EclipseLink 错误?简单的原生 SQL 查询异常

EclipseLink 拒绝将 PostgreSQL 上的本机查询映射到实体

hibernate 和eclipselink的区别