Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to configure a physical naming strategy in hibernate.cfg.xml?

I’m learning Java and Hibernate. Right now, I’m having trouble understanding how to use a custom physical naming strategy: While the PhysicalNamingStrategy object is indeed instantiated, the toPhysicalTableName or toPhysicalColumnName methods are never called – not that I can see with a debugger, at least.

Versions: Java 1.8, Hibernate 5.2.10.Final, on macOS 10.12.

Here’s a minimal project:

@Entity
public class Cake {
    @Id
    private long id;
    private String name;
    private String FLAVOUR;
    private int sErViNg;

    public Cake(String name, String flavour, int serving) {
        this.name = name;
        this.FLAVOUR = flavour;
        this.sErViNg = serving;
    }

    // getters and setters

public class Main {

    public static void main (String[] args) {
        Transaction tx = null;

        try (
                SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
                Session session = sessionFactory.openSession();
        ) {
            tx = session.beginTransaction();

            Cake cake = new Cake("Molten Chocolate Cake", "chocolate", 1);
            session.save(cake);

            tx.commit();
        }
        catch (Exception e) {
            e.printStackTrace();
            if ( tx != null  ) {
                tx.rollback();
            }
        }
    }
}

public class AllCapsPhysicalNamingStrategy
    extends PhysicalNamingStrategyStandardImpl implements Serializable {

    public static final AllCapsPhysicalNamingStrategy INSTANCE
        = new AllCapsPhysicalNamingStrategy();

    @Override
    public Identifier toPhysicalTableName(Identifier name, JdbcEnvironment context) {
        return new Identifier(name.getText().toUpperCase(), name.isQuoted());
    }

    @Override
    public Identifier toPhysicalColumnName(Identifier name, JdbcEnvironment context) {
        return new Identifier(name.getText().toUpperCase(), name.isQuoted());
    }
}

<hibernate-configuration>
    <session-factory>
        <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="hibernate.connection.url">jdbc:mysql://localhost/cake</property>
        <property name="hibernate.connection.username">root</property>
        <property name="hibernate.connection.password"></property>
        <property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>
        <property name="hibernate.hbm2ddl.auto">create</property>
        <property name="hibernate.physical_naming_strategy">com.example.AllCapsPhysicalNamingStrategy</property>
        <mapping class="com.example.Cake"/>
    </session-factory>
</hibernate-configuration>

Here’s the table I get:

[cake]> SELECT * FROM cake;
+----+-----------+-----------------------+---------+
| id | FLAVOUR   | name                  | sErViNg |
+----+-----------+-----------------------+---------+
|  0 | chocolate | Molten Chocolate Cake |       1 |
+----+-----------+-----------------------+---------+

I would expect:

+----+-----------+-----------------------+---------+
| ID | FLAVOUR   | NAME                  | SERVING |
+----+-----------+-----------------------+---------+
|  0 | chocolate | Molten Chocolate Cake |       1 |
+----+-----------+-----------------------+---------+

What am I doing wrong here?

like image 294
Édouard Avatar asked Sep 09 '17 16:09

Édouard


People also ask

Can we rename Hibernate cfg XML?

Yes, you can.

What is Hibernate naming strategy?

Hibernate uses the Physical Naming Strategy to map our logical names to a SQL table and its columns. By default, the physical name will be the same as the logical name that we specified in the previous section. If we want to customize the physical names, we can create a custom PhysicalNamingStrategy class.

How is Hibernate cfg XML loaded?

xml” file in other directory, you can modify the default Hibernate's SessionFactory class by passing your “hibernate. cfg. xml” file path as an argument into the configure() method: SessionFactory sessionFactory = new Configuration() .


2 Answers

This isn't very well documented but unfortunately it seems Hibernate doesn't support that particular property being set in hibernate.cfg.xml. To quote from a very old Hibernate forum post:

You can set the properties given Environment.java class only in hibernate.properties or hibernate.cfg.xml. Rest of the properties like NamingStrategy has to be configured with Configuration class.

So would recommend removing the property and instead setting this in code on the Configuration instance, as proposed by Shiv Raghuwanshi.

like image 75
Steve Chambers Avatar answered Oct 16 '22 01:10

Steve Chambers


You can set in configuration also.

public class Main {

public static void main (String[] args) {
    Transaction tx = null;

    try (
            Configuration configuration =new Configuration();
            configuration.setPhysicalNamingStrategy(new AllCapsPhysicalNamingStrategy());
            SessionFactory sessionFactory = configuration.configure().buildSessionFactory();
            Session session = sessionFactory.openSession();
    ) {
        tx = session.beginTransaction();

        Cake cake = new Cake("Molten Chocolate Cake", "chocolate", 1);
        session.save(cake);

        tx.commit();
    }
    catch (Exception e) {
        e.printStackTrace();
        if ( tx != null  ) {
            tx.rollback();
        }
    }
  }
}
like image 26
Shiv Raghuwanshi Avatar answered Oct 15 '22 23:10

Shiv Raghuwanshi