2011-01-31 2 views
13

Sto provando a forzare JPA/Hibernate per generare e utilizzare solo il nome in miniatura in lettere minuscole. Ho implementato un NamingStrategy come questo:Che cosa significa errore "org.hibernate.DuplicateMappingException"?

public class MyNamingStrategy extends DefaultNamingStrategy { 

    @Override 
    public String classToTableName(String className) { 
    return super.classToTableName(className).toLowerCase(); 
    } 
} 

Ho applicato impostando questa proprietà in persistence.xml:

<property name="hibernate.ejb.naming_strategy" value="entities.strategy.MyNamingStrategy"/> 

Quando faccio questo ottengo questo stacktrace:

SEVERE: Exception while invoking class org.glassfish.persistence.jpa.JPADeployer prepare method 
org.hibernate.DuplicateMappingException: Same physical table name [planning] references several logical table names: [Planning], [OrderProductMan_Planning] 
     at org.hibernate.cfg.Configuration$MappingsImpl.addTableBinding(Configuration.java:2629) 
     at org.hibernate.cfg.annotations.TableBinder.buildAndFillTable(TableBinder.java:254) 
     at org.hibernate.cfg.annotations.TableBinder.bind(TableBinder.java:177) 

Che cosa significa il

Same PHY nome della tabella sica [pianificazione] fa riferimento a diversi nomi di tabelle logiche: [Pianificazione], [OrderProductMan_Planning]

significa?

Entità dell'errore, semplificate il più possibile. Fammi sapere se ti serve il resto.

@Entity 
public class Planning implements Serializable { 

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

    private Integer qty; 

    @ManyToOne 
    private OrderProductMan orderProduct; 

    .... 
} 


@Entity 
@Table 
public class OrderProductMan implements Serializable { 

    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    @Basic(optional = false) 
    private Integer opId; 

    @Basic(optional = false) 
    private int qty; 

    @ManyToOne(optional = false) 
    private ProductMan produse; 

    @ManyToOne(optional = false) 
    private OrderMan orders; 

    @Transient 
    private int totalScheduled; 

    @Transient 
    private int totalProduced; 
    // ... 
} 
+0

Potresti fornire un po 'più di informazioni, come le mappature delle tue entità. – Bozho

+0

Ho aggiornato la mia domanda. Fammi sapere se hai bisogno di più. Grazie! – Bogdan

+0

Sei sicuro di non provare a creare tabelle già esistenti? Il messaggio: 'Lo stesso nome di tabella fisica [pianificazione] fa riferimento a diversi nomi di tabelle logiche: [Pianificazione]' mi fa pensare che la versione maiuscola potrebbe già essere lì e la versione con custodia inferiore non può essere creata. Tenere presente che la maggior parte dei motori DB non fa distinzione tra maiuscole e minuscole. –

risposta

2

Bogdan, grazie per aver postato questo. Ho avuto un problema simile con nomi di tabelle sensibili alle maiuscole/minuscole per la portabilità Unix/Windows usando Hibernate/JPA/MySQL su Linux.

Come te, ho deciso di legare i miei nomi di tabella come tutto minuscolo configurando una consuetudine NamingStrategy nel mio file META-INF/persistence.xml:

<property name="hibernate.ejb.naming_strategy" value="my.package.LowerCaseNamingStrategy" /> 

ho avuto la stessa eccezione: org .hibernate.DuplicateMappingException: Stesso nome della tabella fisica ... Utilizzando il debugger, ho avuto un'illuminazione che forse non stavo usando DefaultNamingStrategy per cominciare! Così ho cambiato la mia classe base in org.hibernate.cfg.EJB3NamingStrategy. Questo è più appropriato quando si usano le annotazioni JPA, credo! Ecco la mia ultima NamingStrategy:

package my.package; 

import org.apache.commons.lang.StringUtils; 
import org.hibernate.cfg.EJB3NamingStrategy; 

public class LowerCaseNamingStrategy extends EJB3NamingStrategy { 
    @Override 
    public String classToTableName(String className) { 
     return StringUtils.lowerCase(super.classToTableName(className)); 
    } 

    @Override 
    public String collectionTableName(String ownerEntity, String ownerEntityTable, String associatedEntity, 
      String associatedEntityTable, String propertyName) { 
     return StringUtils.lowerCase(super.collectionTableName(ownerEntity, ownerEntityTable, associatedEntity, associatedEntityTable, propertyName)); 
    } 

    @Override 
    public String logicalCollectionTableName(String tableName, String ownerEntityTable, String associatedEntityTable, 
      String propertyName) { 
     return StringUtils.lowerCase(super.logicalCollectionTableName(tableName, ownerEntityTable, associatedEntityTable, propertyName)); 
    } 

    @Override 
    public String tableName(String tableName) { 
     return StringUtils.lowerCase(super.tableName(tableName)); 
    } 
} 

PS la soluzione precedente di dursun non ha funzionato per me.

+0

Penso di aver risolto il problema usando ImprovedNamingStrategy. Questo si è occupato di tutto: nomi in minuscolo + caratteri di sottolineatura; Ho anche avuto un'illuminazione: mi sono reso conto che volevo avere il pieno controllo di ciò che stava succedendo, così ho abbandonato il materiale di annotazione/JPA e sono passato alle mappature di ibernazione. Sono stato felice da allora :) – Bogdan