休眠映射异常:实体映射中的重复列
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”中的休眠注释映射异常