【问题标题】:What does "org.hibernate.DuplicateMappingException" error mean?“org.hibernate.DuplicateMappingException”错误是什么意思?
【发布时间】:2011-01-31 15:26:31
【问题描述】:

我正在尝试强制 JPA/Hibernate 生成并仅使用小写的表名。我已经实现了这样的命名策略:

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"/>

当我这样做时,我会得到这个堆栈跟踪:

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)

是什么

相同的物理表名[planning]引用了几个逻辑表名:[Planning]、[OrderProductMan_Planning]

是什么意思?

错误中的实体,尽我所能简化。如果您需要其余的,请告诉我。

@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;
   // ...
 }

【问题讨论】:

  • 您能否提供更多信息 - 例如您的实体的映射。
  • 我已经更新了我的问题。如果您需要更多,请告诉我。谢谢!
  • 您确定您没有尝试创建已经存在的表吗?消息:Same physical table name [planning] references several logical table names: [Planning] 让我认为大写版本可能已经存在,而您的小写版本无法创建。请记住,大多数数据库引擎不区分大小写。

标签: java hibernate jpa java-ee-6 glassfish-3


【解决方案1】:

博格丹,感谢您发布此信息。我在 Linux 上使用 Hibernate/JPA/MySQL 的 Unix/Windows 可移植性的区分大小写的表名也遇到了类似的问题。

和你一样,我开始通过在 META-INF/persistence.xml 文件中配置自定义 NamingStrategy 将我的表名绑定为全部小写:

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

我遇到了同样的异常:org.hibernate.DuplicateMappingException: 相同的物理表名...通过使用调试器,我顿悟了,也许我一开始并没有使用 DefaultNamingStrategy!所以我将我的基类更改为 org.hibernate.cfg.EJB3NamingStrategy。我相信这在使用 JPA Annotations 时更合适!这是我的最终命名策略:

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 之前的解决方案对我不起作用。

【讨论】:

  • 我想我通过使用改进命名策略解决了这个问题。这照顾了一切:小写名称+下划线;我也有一个顿悟:我意识到我想要完全控制正在发生的事情,所以我放弃了 JPA/注释的东西并切换到休眠映射。从那以后我一直很开心:)
猜你喜欢
  • 2019-12-25
  • 1970-01-01
  • 2015-03-04
  • 2012-11-26
  • 2018-05-25
  • 1970-01-01
  • 1970-01-01
  • 2015-06-19
  • 2018-02-18
相关资源
最近更新 更多