2011-01-31 2 views
13

Я пытаюсь заставить JPA/Hibernate генерировать и использовать только строчные табличные имена. Я реализовал NamingStrategy так:Что означает ошибка «org.hibernate.DuplicateMappingException»?

public class MyNamingStrategy extends DefaultNamingStrategy { 

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

я применил его, установив это свойство в persistence.xml:

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

Когда я делаю это я получаю эту 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) 

Что такое

Same phy sical table name [планирование] ссылается на несколько имен логических таблиц: [Планирование], [ЗаказProductMan_Planning]

0?

Сущности от ошибки, упрощенной, насколько я мог. Дайте мне знать, если вам нужно все остальное.

@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

Не могли бы вы предоставить немного больше информации - как отображения ваших объектов. – Bozho

+0

Я обновил свой вопрос. Дайте мне знать, если вам нужно больше. Благодаря! – Bogdan

+0

Вы уверены, что не пытаетесь создать таблицы, которые уже существуют? Сообщение: «То же имя физической таблицы [планирование] ссылается на несколько имен логических таблиц: [Планирование]» заставляет меня думать, что версия верхнего регистра может быть уже там, и ваша нижняя версия с обложкой не может быть создана. Имейте в виду, что большинство БД-систем не чувствительны к регистру. –

ответ

2

Bogdan, спасибо, что опубликовали это. У меня была аналогичная проблема с именами таблиц с учетом регистра для Unix/Windows-переносимости с использованием Hibernate/JPA/MySQL в Linux.

Как и вы, я решил связать свои имена таблиц, как все строчные путем настройки пользовательских NamingStrategy в моем META-INF/persistence.xml файл:

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

Я получил такое же исключение: орг .hibernate.DuplicateMappingException: То же имя физической таблицы ... С помощью отладчика у меня было прозрение, которое может быть Я не использовал DefaultNamingStrategy для начала! Поэтому я изменил базовый класс на org.hibernate.cfg.EJB3NamingStrategy. Я думаю, что это более удобно при использовании JPA Annotations! Вот моя окончательная 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 предыдущее решение dursun не работало для меня.

+0

Я думаю, что я решил проблему, используя ImprovedNamingStrategy. Это позаботилось обо всем: строчные имена + подчеркивания; У меня также было прозрение: я понял, что хочу полностью контролировать то, что происходит, поэтому я удалил материал JPA/аннотации и переключился на спящие сопоставления. Я был счастлив с тех пор :) – Bogdan

Смежные вопросы