I have a problem with JPA and Hibernate and I fail to solve it.
So, it is my 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:
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:
@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
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?.
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"".
@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.
I encountered the same problem, and solved it by changing @Embeddedable
/@EmbeddedId
with @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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With