休眠映射异常:实体映射中的重复列

Posted

技术标签:

【中文标题】休眠映射异常:实体映射中的重复列【英文标题】:Hibernate Mapping Exception : Repeated column in mapping for entity 【发布时间】:2012-03-11 23:14:16 【问题描述】:

特定实体存在映射异常。 无法弄清楚问题出在哪里。 我从头到尾检查了所有映射 3 次。 我仍然得到一个映射异常。

发给员工的电子邮件只映射一次。 但是还是报错repeated mapping

错误是:

Caused by: org.hibernate.MappingException: Repeated column in mapping for entity: com.cluster.entity.Email column: EMPLOYEE_ID (should be mapped with insert="false" update="false")
    at org.hibernate.mapping.PersistentClass.checkColumnDuplication(PersistentClass.java:680)
    at org.hibernate.mapping.PersistentClass.checkPropertyColumnDuplication(PersistentClass.java:702)
    at org.hibernate.mapping.PersistentClass.checkColumnDuplication(PersistentClass.java:724)
    at org.hibernate.mapping.PersistentClass.validate(PersistentClass.java:477)
    at org.hibernate.mapping.RootClass.validate(RootClass.java:268)
    at org.hibernate.cfg.Configuration.validate(Configuration.java:1287)
    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1729)
    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1775)
    at com.cluster.util.HibernateUtil.<clinit>(HibernateUtil.java:16)
    ... 1 more

给 Pojo 发电子邮件

package com.cluster.entity;

public class Email 

    private int intEmailID;
    private String strEmailName;

    //many to one
    private EmailType emailType;

    //many to one
    private Employee employee;

    public int getIntEmailID() 
        return intEmailID;
    

    public void setIntEmailID(int intEmailID) 
        this.intEmailID = intEmailID;
    

    public String getStrEmailName() 
        return strEmailName;
    

    public void setStrEmailName(String strEmailName) 
        this.strEmailName = strEmailName;
    

    public EmailType getEmailType() 
        return emailType;
    

    public void setEmailType(EmailType emailType) 
        this.emailType = emailType;
    

    public Employee getEmployee() 
        return employee;
    

    public void setEmployee(Employee employee) 
        this.employee = employee;
    


email.hbm.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
        '-//Hibernate/Hibernate Mapping DTD 3.0//EN'
        'http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd'>


<hibernate-mapping package="com.cluster.entity" >
    <class name="Email" table="EMAIL">

        <id name="intEmailID" column="EMAIL_ID"> 
            <generator class="sequence">
                <param name="sequence">EMAIL_ID_SEQ</param>
            </generator>
        </id>

        <property name="strEmailName" column = "EMAIL_NAME"/>

        <many-to-one name="employee" column="EMPLOYEE_ID" not-null = "true" class = "Employee"/>

        <many-to-one name="emailType" column="EMAIL_TYPE_ID" not-null = "true" class = "EmailType"/>

    </class>

</hibernate-mapping>

相关脚本

CREATE TABLE EMPLOYEE
(
  EMPLOYEE_ID      NUMBER                       NOT NULL,
  FIRSTNAME        VARCHAR2(20 BYTE)            NOT NULL,
  LASTNAME         VARCHAR2(20 BYTE)            NOT NULL,
  DATE_OF_BIRTH    VARCHAR2(20 BYTE)            NOT NULL,
  SALARY           VARCHAR2(10 BYTE)            NOT NULL,
  DEPARTMENT_ID    NUMBER                       NOT NULL
);


CREATE TABLE EMAIL
(
 EMAIL_ID              NUMBER              NOT NULL,
 EMAIL_NAME            VARCHAR2(40 BYTE)   NOT NULL,
 EMPLOYEE_ID           NUMBER              NOT NULL,
 EMAIL_TYPE_ID         NUMBER              NOT NULL
);


CREATE TABLE EMAIL_TYPE
(
 EMAIL_TYPE_ID         NUMBER              NOT NULL,
 EMAIL_TYPE_NAME       VARCHAR2(40 BYTE)   NOT NULL
);


ALTER TABLE EMPLOYEE ADD 
(
 CONSTRAINT PK_EMPLOYEE_ID
 PRIMARY KEY (EMPLOYEE_ID)
);

ALTER TABLE EMAIL_TYPE ADD 
(
 CONSTRAINT PK_EMAIL_TYPE_ID
 PRIMARY KEY (EMAIL_TYPE_ID)
);

ALTER TABLE EMAIL ADD
(
 CONSTRAINT PK_EMAIL_ID
 PRIMARY KEY (EMAIL_ID)
);

ALTER TABLE EMAIL ADD
( 
 CONSTRAINT FK_EMAIL_EMPLOYEE_ID
 FOREIGN KEY (EMPLOYEE_ID)
 REFERENCES EMPLOYEE (EMPLOYEE_ID)
);

ALTER TABLE EMAIL ADD
( 
 CONSTRAINT FK_EMAIL_EMAIL_TYPE_ID
 FOREIGN KEY (EMAIL_TYPE_ID)
 REFERENCES EMAIL_TYPE (EMAIL_TYPE_ID)
);

发给员工的电子邮件只映射一次。 但是还是报错repeated mapping

【问题讨论】:

【参考方案1】:

您是否将 Employee 中的集合设置为反向?

<bag name="emails" inverse="true">
  <key column="EMPLOYEE_ID" not-null="true">
  ...
</bag>

【讨论】:

inverse 表示 Child (Email) 负责关联。所以孩子是EMPLOYEE_ID 的所有者,必须插入/更新它。父级仅使用该字段来了解其子级,但不插入/更新它 同样,我在双向关系的两边都有@JoinColumn。然而,这个模棱两可的错误信息让我陷入了一场刚刚结束的疯狂追逐。【参考方案2】:

对于那些使用注解来解决这个问题的人来说,类应该是这样的:

@Entity
public class Email 

    @Id
    @GeneratedValue(strategy=GenerationType.SEQUENCE)
    private int intEmailID;

    @Column(insertable = false, updatable = false)
    private int employeeId;

    @ManyToOne
    private EmailType emailType;

    @ManyToOne
    @JoinColumn(name="employeeId")
    private Employee employee;

    // Getters and Setter



@Entity
public class Employee 

    @Id
    private int id;

    @OneToMany(cascade = CascadeType.ALL, mappedBy="employeeId")
    @PrimaryKeyJoinColumn
    private List<Email> emailList;

    public void setEmailList(List<Email> emailList) 
        this.emailList = emailList
    

    public List<Email> getEmailList() 
        return emailList;
    

    // Rest of getters and setters


【讨论】:

【参考方案3】:

我认为您已使用 oneToMany 关系将 Employee 映射到 Email。如果是,则没有错,但您必须确保只能在一个方向插入和更新

应该在Employee中用insert="false" update="false"映射

【讨论】:

是的......你是对的!我试过了.. 我们要么做 inverse = "true",要么照你说的做!

以上是关于休眠映射异常:实体映射中的重复列的主要内容,如果未能解决你的问题,请参考以下文章

休眠查询以匹配映射实体集合与给定集合中的至少一个元素,多对多关系

Spring MVC“org.hibernate.PropertyAccessException”中的休眠注释映射异常

休眠位数组到实体映射

休眠中的映射列表<CustomClass> - ClassCastException

将 tinyint 映射为布尔休眠

使休眠忽略未映射的类变量[重复]