外键和引用类如何在 Hibernate 实体中一起存在?
Posted
技术标签:
【中文标题】外键和引用类如何在 Hibernate 实体中一起存在?【英文标题】:How can foreign key and reference class live together in a Hibernate entity? 【发布时间】:2014-06-05 02:34:57 【问题描述】:我正在使用生成工具生成 Hibernate 实体,我收到如下错误:
Caused by: org.hibernate.MappingException: Repeated column in mapping for entity: model.PayLogEntity column: brank_card_id (should be mapped with insert="false" update="false")
at org.hibernate.mapping.PersistentClass.checkColumnDuplication(PersistentClass.java:676)
at org.hibernate.mapping.PersistentClass.checkPropertyColumnDuplication(PersistentClass.java:698)
at org.hibernate.mapping.PersistentClass.checkColumnDuplication(PersistentClass.java:720)
at org.hibernate.mapping.PersistentClass.validate(PersistentClass.java:474)
at org.hibernate.mapping.RootClass.validate(RootClass.java:235)
at org.hibernate.cfg.Configuration.validate(Configuration.java:1362)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1865)
at org.springframework.orm.hibernate3.LocalSessionFactoryBean.newSessionFactory(LocalSessionFactoryBean.java:860)
at org.springframework.orm.hibernate3.LocalSessionFactoryBean.buildSessionFactory(LocalSessionFactoryBean.java:779)
at org.springframework.orm.hibernate3.AbstractSessionFactoryBean.afterPropertiesSet(AbstractSessionFactoryBean.java:188)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1514)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1452)
... 67 more
抛出错误的类如下:
package model;
import javax.persistence.*;
import java.sql.Timestamp;
/**
* Created by shenshijun on 14-6-5.
*/
@Entity
@Table(name = "pay_log", schema = "", catalog = "healthclube")
public class PayLogEntity
private int id;
private Integer userId;
private String brankCardId;
private String payType;
private Timestamp payTime;
private Double count;
private String message;
private BankCardEntity bankCardByBrankCardId;
@Id
@Column(name = "id")
public int getId()
return id;
public void setId(int id)
this.id = id;
@Basic
@Column(name = "user_id")
public Integer getUserId()
return userId;
public void setUserId(Integer userId)
this.userId = userId;
@Basic
@Column(name = "brank_card_id")
public String getBrankCardId()
return brankCardId;
public void setBrankCardId(String brankCardId)
this.brankCardId = brankCardId;
@Basic
@Column(name = "pay_type")
public String getPayType()
return payType;
public void setPayType(String payType)
this.payType = payType;
@Basic
@Column(name = "pay_time")
public Timestamp getPayTime()
return payTime;
public void setPayTime(Timestamp payTime)
this.payTime = payTime;
@Basic
@Column(name = "count")
public Double getCount()
return count;
public void setCount(Double count)
this.count = count;
@Basic
@Column(name = "message")
public String getMessage()
return message;
public void setMessage(String message)
this.message = message;
@Override
public boolean equals(Object o)
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
PayLogEntity that = (PayLogEntity) o;
if (id != that.id) return false;
if (brankCardId != null ? !brankCardId.equals(that.brankCardId) : that.brankCardId != null) return false;
if (count != null ? !count.equals(that.count) : that.count != null) return false;
if (message != null ? !message.equals(that.message) : that.message != null) return false;
if (payTime != null ? !payTime.equals(that.payTime) : that.payTime != null) return false;
if (payType != null ? !payType.equals(that.payType) : that.payType != null) return false;
if (userId != null ? !userId.equals(that.userId) : that.userId != null) return false;
return true;
@Override
public int hashCode()
int result = id;
result = 31 * result + (userId != null ? userId.hashCode() : 0);
result = 31 * result + (brankCardId != null ? brankCardId.hashCode() : 0);
result = 31 * result + (payType != null ? payType.hashCode() : 0);
result = 31 * result + (payTime != null ? payTime.hashCode() : 0);
result = 31 * result + (count != null ? count.hashCode() : 0);
result = 31 * result + (message != null ? message.hashCode() : 0);
return result;
@ManyToOne
@JoinColumn(name = "brank_card_id", referencedColumnName = "id")
public BankCardEntity getBankCardByBrankCardId()
return bankCardByBrankCardId;
public void setBankCardByBrankCardId(BankCardEntity bankCardByBrankCardId)
this.bankCardByBrankCardId = bankCardByBrankCardId;
看来实体中的brank_card_id
有两次beaning映射,一次是getBrankCardId
,另一次是getBankCardByBrankCardId
。所以我的问题是如何更改代码以消除冲突?
【问题讨论】:
其实我发现了一个类似的问题link 会有所帮助。 【参考方案1】:Hibernate 的意思是您在此表中定义了 2 列,名称为 brank_card_id
。一种是:
@Basic
@Column(name = "brank_card_id")
public String getBrankCardId()
return brankCardId;
另一个是:
@ManyToOne
@JoinColumn(name = "brank_card_id", referencedColumnName = "id")
public BankCardEntity getBankCardByBrankCardId()
return bankCardByBrankCardId;
@JoinColumn
注解的name属性是外键列的实际名称。
您不能有 2 个名为 brank_card_id
的列。不要将您的加入列称为brank_card_id
,而是将其称为其他名称,例如bank_card_fk
。任何事情都应该有效。只需确保在关系的另一端正确引用它即可。
更改@JoinColumn
注释以匹配以下内容:
@ManyToOne
@JoinColumn(name = "bank_card_fk", referencedColumnName = "id")
public BankCardEntity getBankCardByBrankCardId()
return bankCardByBrankCardId;
【讨论】:
@JoinColumn(name = "brank_card_id", referencedColumnName = "id")
。您不能将名称更改为brank_card_id
到brank_card_pk
,因为brank_card_id
映射到表中的列,而brank_card_pk
甚至不存在于表中。
我明白了你的想法,但我认为这不是一个好主意。因为您建议的更改使这一侧的映射无用,而在另一侧我有:@OneToMany(mappedBy = "userByUserId") public Collection<BankCardEntity> getBankCardsById() return bankCardsById;
。所以这些变化会使映射失败
但是您上面的@OneToMany
注释甚至不会指向PayLogEntity
对象和相应的表。它将指向BankCardEntity
对象和表。以上是关于外键和引用类如何在 Hibernate 实体中一起存在?的主要内容,如果未能解决你的问题,请参考以下文章