2013-02-25 12 views
56

Nonostante tutti gli altri post, non riesco a trovare una soluzione per questo errore con GlassFish, su MacOSX, NetBeans 7.2.Un'altra colonna ripetuta nella mappatura per errore di entità

Here the error : 
SEVERE: Exception while invoking class org.glassfish.persistence.jpa.JPADeployer 
prepare method 
SEVERE: Exception while preparing the app 
SEVERE: [PersistenceUnit: supmarket] Unable to build EntityManagerFactory 

... 

Caused by: org.hibernate.MappingException: Repeated column in mapping for entity: 
com.supmarket.entity.Sale column: customerId 
(should be mapped with insert="false" update="false") 

Ecco il codice:

Sale.java

@Entity 
public class Sale { 

    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private Long id; 

    @Column(nullable=false) 
    private Long idFromAgency; 

    private float amountSold; 

    private String agency; 

    @Temporal(javax.persistence.TemporalType.DATE) 
    private Date createdate; 

    @Column(nullable=false) 
    private Long productId; 

    @Column(nullable=false) 
    private Long customerId; 

    @ManyToOne(optional=false) 
    @JoinColumn(name="productId",referencedColumnName="id_product") 
    private Product product; 

    @ManyToOne(optional=false) 
    @JoinColumn(name="customerId",referencedColumnName="id_customer") 
    private Customer customer; 


    public void Sale(){}  
    public void Sale(Long idFromAgency, float amountSold, String agency 
      , Date createDate, Long productId, Long customerId){   
     ... 
    } 

    // then getters/setters 
} 

Customer.java

@Entity 
public class Customer { 

    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    @Column(name="id_customer") 
    private Long id_customer; 

    @Column(nullable=false) 
    private Long idFromAgency; 

    private String gender, 
        maritalState, 
        firstname, 
        lastname, 
        incomeLevel; 

    @OneToMany(mappedBy="customer",targetEntity=Sale.class, fetch=FetchType.EAGER) 
    private Collection sales; 


    public void Customer(){} 

    public void Customer(Long idFromAgency, String gender, String maritalState, 
      String firstname, String lastname, String incomeLevel) { 
     ... 
    } 

} 

Product.java

public class Product { 

    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    @Column(name="id_product") 
    private Long id_product; 

    @Column(nullable=false) 
    private Long idFromAgency; 

    private String name; 

    @OneToMany(mappedBy="product",targetEntity=Sale.class, fetch=FetchType.EAGER) 
    private Collection sales; 

    //constructors + getters +setters 
} 

risposta

70

Il messaggio è chiaro: si dispone di una colonna ripetuta nella mappatura. Ciò significa che hai mappato la stessa colonna del database due volte. E in effetti, si ha:

@Column(nullable=false) 
private Long customerId; 

e anche:

@ManyToOne(optional=false) 
@JoinColumn(name="customerId",referencedColumnName="id_customer") 
private Customer customer; 

(e lo stesso vale per productId/product).

Non si deve fare riferimento ad altre entità tramite il loro ID, ma mediante un riferimento diretto all'entità. Rimuovi il campo customerId, è inutile. E fare lo stesso per productId. Se si desidera che l'ID cliente di una vendita, non vi resta che fare questo:

sale.getCustomer().getId() 
+0

ottengo lo stesso errore, ma la mia situazione è un po 'diverso. La mia entità può essere il padre di una o più entità dello stesso tipo. I bambini hanno un riferimento sull'id del padre e un id unico. Come posso risolvere una dipendenza così circolare? – Serban

+0

@Serban Fai la tua domanda, con il codice. –

+0

@JBNizet In che modo posso * salvare * una vendita con un particolare 'customerId'? (ad esempio da JSON). –

33

Se sei bloccato con un database legacy dove qualcuno già collocato annotazioni APP su ma non ha definito le relazioni e si sta ora tentando per definirli per l'uso nel tuo codice, potresti NON essere in grado di eliminare customerId @Column poiché altri codici potrebbero già farne riferimento direttamente. In tal caso, definire le relazioni come segue:

@ManyToOne(optional=false) 
@JoinColumn(name="productId",referencedColumnName="id_product", insertable=false, updatable=false) 
private Product product; 

@ManyToOne(optional=false) 
@JoinColumn(name="customerId",referencedColumnName="id_customer", insertable=false, updatable=false) 
private Customer customer; 

Ciò consente di accedere alle relazioni. Tuttavia, per aggiungere/aggiornare alle relazioni, sarà necessario manipolare le chiavi esterne direttamente tramite i loro valori @Column definiti. Non è una situazione ideale, ma se ti viene consegnato questo tipo di situazione, almeno puoi definire le relazioni in modo da poter utilizzare correttamente JPQL.

+0

Grazie, questa è esattamente la soluzione di cui ho bisogno , oltre al campo di mappatura 'ManyToOne', ho bisogno di un campo direttamente mappato alla colonna di join. – ryenus

+0

Questa è la soluzione giusta quando si dispone di un campo che è chiave esterna e chiave primaria allo stesso tempo. – AntuanSoft

7
@Id 
@Column(name = "COLUMN_NAME", nullable = false) 
public Long getId() { 
    return id; 
} 

@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, targetEntity = SomeCustomEntity.class) 
@JoinColumn(name = "COLUMN_NAME", referencedColumnName = "COLUMN_NAME", nullable = false, updatable = false, insertable = false) 
@org.hibernate.annotations.Cascade(value = org.hibernate.annotations.CascadeType.ALL) 
public List<SomeCustomEntity> getAbschreibareAustattungen() { 
    return abschreibareAustattungen; 
} 

Se è già stato mappato una colonna e hanno accidentalmente impostare gli stessi valori per nome e referencedColumnName in @JoinColumn ibernazione dà lo stesso errore stupido

Errore:

Causato da: org.hibernate.MappingException: colonna ripetuta nel mapping per entità: colonna com.testtest.SomeCustomEntity: COLUMN_NAME (deve essere associata con ins ert = "false" update = "false")

+0

Un punto chiave per me era che l'errore dice "dovrebbe essere mappato con insert = false update = false" ma i parametri/metodi attuali dovrebbero essere "insertable = false, updatable = false". –

0

Fare attenzione a fornire solo 1 setter e getter per qualsiasi attributo.Il modo migliore per avvicinarsi è scrivere la definizione di tutti gli attributi, quindi utilizzare eclipse generare setter e utility getter invece di farlo manualmente. L'opzione si attiva con il tasto destro del mouse-> fonte -> Genera Getter e Setter.

4

uso questo, è lavoro per me:

@Column(name = "candidate_id", nullable=false) 
private Long candidate_id; 
@ManyToOne(optional=false) 
@JoinColumn(name = "candidate_id", insertable=false, updatable=false) 
private Candidate candidate; 
+0

Grazie, questa è esattamente la soluzione di cui ho bisogno –

Problemi correlati