2011-01-31 686 views
13

Estoy intentando obligar a JPA/Hibernate a generar y usar solo nombres de tablas en minúsculas. He implementado un NamingStrategy así:¿Qué significa el error "org.hibernate.DuplicateMappingException"?

public class MyNamingStrategy extends DefaultNamingStrategy { 

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

he aplicado mediante el establecimiento de esta propiedad en persistence.xml:

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

Cuando hago esto consigo este 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) 

¿Qué significa la

Same phy El nombre de tabla sical [planificación] hace referencia a varios nombres de tabla lógica: [Planificación], [OrderProductMan_Planning]

mean?

Entidades del error, simplificadas tanto como pude. Avísame si necesitas el 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

Podría proporcionarnos un poco más de información, como las asignaciones de sus entidades. – Bozho

+0

He actualizado mi pregunta. Avíseme si necesita más. ¡Gracias! – Bogdan

+0

¿Estás seguro de que no estás intentando crear tablas que ya existen? El mensaje: 'Mismo nombre de tabla física [planificación] hace referencia a varios nombres de tablas lógicas: [Planificación]' me hace pensar que la versión en mayúsculas podría estar allí y no se puede crear la versión de la carcasa inferior. Tenga en cuenta que la mayoría de los motores de DB no distinguen entre mayúsculas y minúsculas. –

Respuesta

2

Bogdan, gracias por publicar esto. Tuve un problema similar con los nombres de tablas sensibles a mayúsculas y minúsculas para la portabilidad de Unix/Windows usando Hibernate/JPA/MySQL en Linux.

Al igual que usted, me puse a atar mis nombres de tabla como todo en minúsculas mediante la configuración de una costumbre NamingStrategy en mi archivo/persistence.xml META-INF:

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

que tiene la misma excepción: org .hibernate.DuplicateMappingException: Mismo nombre de tabla física ... Mediante el uso del depurador, tuve una epifanía que tal vez ¡No estaba usando DefaultNamingStrategy para empezar! Así que cambié mi clase base a org.hibernate.cfg.EJB3NamingStrategy. Esto es más apropiado cuando uso Anotaciones JPA, ¡creo! Aquí fue mi última 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 solución anterior por dursun no funcionó para mí.

+0

Creo que he resuelto el problema usando ImprovedNamingStrategy. Esto se encargó de todo: nombres en minúsculas + guiones bajos; También tuve una epifanía: me di cuenta de que quería un control total de lo que estaba sucediendo, así que abandoné el material de las anotaciones/JPA y cambié a las asignaciones de hibernación. He estado feliz desde entonces :) – Bogdan

Cuestiones relacionadas