2015-04-29 11 views
5

Mam problem z JPA i Hibernate i nie uda mi się go rozwiązać.Osadzony identyfikator i "powtarzana kolumna w odwzorowaniu dla encji ..." wyjątek

Tak, to jest mój 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> 

To moja jednostka Wydajność:

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 } 

A to moja osadzone klasa 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 

Więc, to są moje klasy. Ale gdy chcę uruchomić mojej aplikacji mam kolejne wyjątki: 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") 

myślę, że pierwszy wyjątek to spowodowane przez sekundę. Dlaczego pojawia się "Powtarzana kolumna w mapowaniu dla jednostki?". Dobrze jest użyć klasy embedded id.

Odpowiedz

9

Twoje dwie zmienne match i player w swojej klasie Performance są przypisane do tych samych kolumn jako matchId i playerId w osadzonym ID. Jak informuje błąd, "powinny być odwzorowane za pomocą 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; 

To w istocie czyni te pola tylko do odczytu, więc Hibernate wie tylko zmienić MATCH_ID i PLAYER_ID kolumny jeśli wartości w osadzonym ID zostaną zmienione, ale nie wtedy, gdy wartości match lub player są zmieniane.

+0

zmienić jak mówisz, ale to nie działa :(. – Rapidistul

+0

Czy to daje ten sam błąd? Inny błąd? – forgivenson

+0

ten sam błąd. – Rapidistul

0

Może to być możliwe za pomocą @EmbeddedId, ale może być łatwiej użyć adnotacji @IdClass na poziomie jednostki. Następnie można ustawić @Id adnotacji na @ManyToOne odniesień bezpośrednio:

@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 zdefiniowano klasę PerformancePK jako wewnętrzna klasy, ponieważ uważam, że to wygodne, ale to nie musi być.

-1

Napotkałem ten sam problem i rozwiązałem go, zmieniając @Embeddedable/@EmbeddedId na @IdClass.

swoich klas powinien wyglądać (i pomijają pewne informacje):

@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 
} 

Przy tej konstrukcji, struktury DB nadal taka sama. Więcej informacji o @IdClass usage.

Powiązane problemy