java 嵌入的 id 和“实体映射中的重复列...”异常
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/29952386/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Embedded id and "repeated column in mapping for entity..." exception
提问by Rapidistul
I have a problem with JPA and Hibernate and I fail to solve it.
我在使用 JPA 和 Hibernate 时遇到问题,但无法解决。
So, it is my applicationContext.xml:
所以,这是我的 applicationContext.xml:
<context:component-scan base-package="com.abt.fiifootballmanager">
<context:exclude-filter type="annotation"
expression="org.springframework.stereotype.Controller" />
</context:component-scan>
<jdbc:embedded-database type="HSQL" id="dataSource" />
<bean
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
id="emf">
<property name="packagesToScan" value="com.abt.fiifootballmanager.entity" />
<property name="dataSource" ref="dataSource" />
<property name="jpaProperties">
<props>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">create</prop>
</props>
</property>
<property name="persistenceProvider">
<bean class="org.hibernate.jpa.HibernatePersistenceProvider" />
</property>
</bean>
<tx:annotation-driven transaction-manager="transactionManager"/>
<bean class="org.springframework.orm.jpa.JpaTransactionManager" id="transactionManager">
<property name="dataSource" value="dataSource"/>
</bean>
This is my Performance entity:
这是我的 Performance 实体:
package com.abt.fiifootballmanager.entity;
import java.io.Serializable;
import javax.persistence.*;
import java.math.BigDecimal;
import java.util.List;
@Entity
@Table(name="PERFORMANCES")
@NamedQuery(name="Performance.findAll", query="SELECT p FROM Performance p")
public class Performance implements Serializable {
private static final long serialVersionUID = 1L;
@EmbeddedId
private PerformancePK id;
@Column(name="RED_CARD")
private BigDecimal redCard;
@Column(name="YELLOW_CARD")
private BigDecimal yellowCard;
@OneToOne(mappedBy="performance")
private GoalkeepingPerformance goalkeepingPerformance;
@OneToMany(mappedBy="performance")
private List<OutfieldPerformance> outfieldPerformances;
@ManyToOne
@JoinColumn(name="MATCH_ID")
private Match match;
@ManyToOne
@JoinColumn(name="PLAYER_ID")
private Player player;
...getters & setters }
And this is my embedded id class:
这是我嵌入的 id 类:
@Embeddable
public class PerformancePK implements Serializable {
//default serial version id, required for serializable classes.
private static final long serialVersionUID = 1L;
@Column(name="MATCH_ID", insertable=false, updatable=false)
private long matchId;
@Column(name="PLAYER_ID", insertable=false, updatable=false)
private long playerId;
... //getters and setters
So, these are my classes. But when I want to run my application I get the next exceptions:
1.Error creating bean with name 'emf' defined in ServletContext resource [/WEB-INF/applicationContext.xml]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory
所以,这些是我的课程。但是当我想运行我的应用程序时,我得到了下一个例外:
1.Error creating bean with name 'emf' defined in ServletContext resource [/WEB-INF/applicationContext.xml]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory
2. Repeated column in mapping for entity: com.abt.fiifootballmanager.entity.Performance column: MATCH_ID (should be mapped with insert="false" update="false")
I think that the first exception it's caused by the second. So, why I get "Repeated column in mapping for entity?". It's a good idea to use an embedded id class?.
我认为第一个例外是由第二个引起的。那么,为什么我会得到“实体映射中的重复列?”。使用嵌入式 id 类是个好主意吗?。
回答by forgivenson
Your two variables match
and player
in your Performance
class are mapped to the same columns as matchId
and playerId
in the embedded ID. As the error says, they "should be mapped with insert="false" update="false"".
你的两个变量match
,并player
在你的Performance
类被映射到相同的列matchId
和playerId
嵌入式ID。正如错误所说,它们“应该用 insert="false" update="false"” 映射。
@ManyToOne
@JoinColumn(name="MATCH_ID", insertable = false, updatable = false)
private Match match;
@ManyToOne
@JoinColumn(name="PLAYER_ID", insertable = false, updatable = false)
private Player player;
This essentially makes those fields readonly, so Hibernate knows only to change the MATCH_ID
and PLAYER_ID
columns if the values in the embedded ID are changed, but not if the values of match
or player
are changed.
这实质上使这些字段成为只读的,因此 Hibernate 只知道在嵌入 ID 中的值更改时更改MATCH_ID
和PLAYER_ID
列,而不知道match
或的值player
更改时更改。
回答by Eugene
I encountered the same problem, and solved it by changing @Embeddedable
/@EmbeddedId
with @IdClass
.
我遇到了同样的问题,并通过将@Embeddedable
/更改@EmbeddedId
为@IdClass
.
Your classes should look like (i omit some info):
你的课程应该看起来像(我省略了一些信息):
@Entity
@Table(name="PERFORMANCES")
@IdClass(PerformancePK.class)
public class Performance implements Serializable {
@Id
@Column(name="MATCH_ID")
private long matchId;
@Id
@Column(name="PLAYER_ID")
private long playerId;
@ManyToOne
@JoinColumn(name="MATCH_ID", insertable = false, updatable = false)
private Match match;
@ManyToOne
@JoinColumn(name="PLAYER_ID", insertable = false, updatable = false)
private Player player;
...//getters, setters
}
public class PerformancePK implements Serializable {
private long matchId;
private long playerId;
... //getters and setters
// !!! MANDATORY: override hashCode() and equals() here
}
With this construction, your DB structure still the same. More information about @IdClass usage.
通过这种结构,您的数据库结构仍然相同。有关@IdClass 用法的更多信息。
回答by David Levesque
It may be possible to do this using @EmbeddedId
, but it may be easier to use the @IdClass
annotation at the entity level. You can then set the @Id
annotation on the @ManyToOne
references directly:
可以使用 来执行此操作@EmbeddedId
,但@IdClass
在实体级别使用注释可能更容易。然后,您可以直接@Id
在@ManyToOne
引用上设置注释:
@Entity
@Table(name="PERFORMANCES")
@IdClass(PerformancePK.class)
@NamedQuery(name="Performance.findAll", query="SELECT p FROM Performance p")
public class Performance implements Serializable {
static public class PerformancePK implements Serializable {
private long match;
private long player;
public PerformancePK() {
}
public PerformancePK(long match, long player) {
this.match = match;
this.player = player;
}
// TODO: implements equals() and hashCode()
}
@Id
@ManyToOne
@JoinColumn(name="MATCH_ID")
private Match match;
@Id
@ManyToOne
@JoinColumn(name="PLAYER_ID")
private Player player;
...
}
I have defined the PerformancePK class as an inner class because I find it convenient, but it doesn't have to be.
我已将 PerformancePK 类定义为内部类,因为我觉得它很方便,但并非必须如此。