简体   繁体   English

嵌入式id和“实体映射中的重复列...”异常

[英]Embedded id and “repeated column in mapping for entity…” exception

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 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类是个好主意?

Your two variables match and player in your Performance class are mapped to the same columns as matchId and playerId in the embedded ID. 您的两个变量matchPerformance类中的player映射到嵌入ID中与matchIdplayerId相同的列。 As the error says, they "should be mapped with insert="false" update="false"". 正如错误所说,它们“应该用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. 这实际上使这些字段只读,因此如果嵌入ID中的值发生更改,Hibernate只知道更改MATCH_IDPLAYER_ID列,但是如果更改了matchplayer的值则不知道。

It may be possible to do this using @EmbeddedId , but it may be easier to use the @IdClass annotation at the entity level. 可以使用@EmbeddedId执行此操作,但在实体级别使用@IdClass注释可能更容易。 You can then set the @Id annotation on the @ManyToOne references directly: 然后,您可以直接在@ManyToOne引用上设置@Id注释:

@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类定义为内部类,因为我发现它很方便,但它不一定非常。

I encountered the same problem, and solved it by changing @Embeddedable / @EmbeddedId with @IdClass . 我遇到了同样的问题,并通过使用@IdClass更改@Embeddedable / @EmbeddedId来解决它。

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用法的更多信息。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM