13

I'm trying to force JPA/Hibernate to generate and use only lowercase tablenames. I've implemented a NamingStrategy like this:

public class MyNamingStrategy extends DefaultNamingStrategy {

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

I have applied it by setting this property in persistence.xml:

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

When I do this I get this 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)

What does the

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

mean?

Entities from the error, simplified as much as I could. Let me know if you need the rest.

@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;
   // ...
 }
3
  • Could you provide a bit more info - like the mappings of your entities. Commented Jan 31, 2011 at 15:30
  • I've updated my question. Let me know if you need more. Thanks! Commented Jan 31, 2011 at 15:42
  • Are you sure you are not trying to create tables that already exist? The message: Same physical table name [planning] references several logical table names: [Planning] makes me think that the uppercase version might already be there and your lower cased version can't be created. Keep in mind that most DB engines are not case sensitive. Commented May 13, 2011 at 20:04

1 Answer 1

2

Bogdan, thanks for posting this. I had a similar problem with case-sensitive table names for Unix/Windows portability using Hibernate/JPA/MySQL on Linux.

Like you, I set out to bind my table names as all lower-case by configuring a custom NamingStrategy in my META-INF/persistence.xml file:

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

I got the same exception: org.hibernate.DuplicateMappingException: Same physical table name... Through using the debugger, I had an epiphany that maybe I wasn't using DefaultNamingStrategy to begin with! So I changed my base class to org.hibernate.cfg.EJB3NamingStrategy. This is more appropriate when using JPA Annotations, I believe! Here was my final 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 the previous solution by dursun did not work for me.

Sign up to request clarification or add additional context in comments.

1 Comment

I think I solved the problem by using ImprovedNamingStrategy. This took care of everything: lowercase names+underscores; I also had an epiphany: I realized I want full control of what's happening so I ditched the JPA/annotation stuff and switched to hibernate mappings. I've been happy ever since :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.