13 Stimmen

Was bedeutet der Fehler "org.hibernate.DuplicateMappingException"?

Ich versuche, JPA/Hibernate dazu zu zwingen, nur Tabellennamen in Kleinbuchstaben zu generieren und zu verwenden. Ich habe eine NamingStrategy wie folgt implementiert:

public class MyNamingStrategy extends DefaultNamingStrategy {

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

Ich habe es angewendet, indem ich diese Eigenschaft in der persistence.xml gesetzt habe:

Wenn ich das mache, erhalte ich diesen 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)

Was bedeutet das

Same physical table name [planning] references several logical table names: [Planning], [OrderProductMan_Planning]

?

Entitäten aus dem Fehler, so einfach wie möglich dargestellt. Lassen Sie mich wissen, wenn Sie den Rest benötigen.

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

Könnten Sie etwas mehr Informationen bereitstellen - wie zum Beispiel die Zuordnungen Ihrer Entitäten.

0 Stimmen

Ich habe meine Frage aktualisiert. Lass mich wissen, wenn du mehr brauchst. Danke!

0 Stimmen

Sind Sie sicher, dass Sie versuchen, Tabellen zu erstellen, die bereits vorhanden sind? Die Meldung: Gleicher physischer Tabellenname [planning] verweist auf mehrere logische Tabellennamen: [Planung] lässt mich vermuten, dass die Großbuchstaben-Version bereits vorhanden sein könnte und Ihre Kleinbuchstaben-Version nicht erstellt werden kann. Beachten Sie, dass die meisten DB-Engines nicht auf Groß- und Kleinschreibung achten.

2voto

Steve Jones Punkte 1430

Bogdan, danke für das Posten. Ich hatte ein ähnliches Problem mit Groß- und Kleinschreibung in Tabellennamen für die Portabilität zwischen Unix/Windows mit Hibernate/JPA/MySQL auf Linux.

Wie du habe ich versucht, meine Tabellennamen alle in Kleinbuchstaben zu binden, indem ich eine benutzerdefinierte NamingStrategy in meiner META-INF/persistence.xml-Datei konfiguriert habe:

Ich erhielt dieselbe Ausnahme: org.hibernate.DuplicateMappingException: Gleicher physischer Tabellenname... Durch Verwendung des Debuggers hatte ich eine Eingebung, dass vielleicht ich von Anfang an nicht DefaultNamingStrategy verwendet habe! Also änderte ich meine Basisklasse zu org.hibernate.cfg.EJB3NamingStrategy. Dies ist meiner Meinung nach angemessener bei Verwendung von JPA-Annotationen! Hier war meine endgültige 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 die vorherige Lösung von dursun hat bei mir nicht funktioniert.

0 Stimmen

Ich denke, ich habe das Problem gelöst, indem ich ImprovedNamingStrategy verwendet habe. Das hat sich um alles gekümmert: Kleinbuchstaben + Unterstriche; Ich hatte auch eine Erleuchtung: Ich merkte, dass ich die volle Kontrolle darüber haben möchte, was passiert, also habe ich die JPA/Annotationssachen verworfen und auf Hibernate-Mappings umgestellt. Seitdem bin ich glücklich :)

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X