Подтвердить что ты не робот

Как настроить стратегию именования в hibernate.cfg.xml?

Я изучаю Java и Hibernate. Прямо сейчас у меня возникли проблемы с пониманием того, как использовать пользовательскую стратегию физического именования. Хотя объект PhysicalNamingStrategy действительно создан, методы toPhysicalTableName или toPhysicalColumnName никогда не вызываются - не то, что я могу видеть с помощью отладчика, по крайней мере.

Версии: Java 1.8, Hibernate 5.2.10.Final, на macOS 10.12.

Вот минимальный проект:

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

Вот таблица, которую я получаю:

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

Я бы ожидал:

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

Что я здесь делаю неправильно?

4b9b3361

Ответ 1

Это не очень хорошо документировано, но, к сожалению, кажется, что Hibernate не поддерживает это конкретное свойство, установленное в файле hibernate.cfg.xml. Процитировать очень старое сообщение форума Hibernate:

Вы можете установить свойства, указанные в классе Environment.java, только в hibernate.properties или hibernate.cfg.xml. Остальные свойства, такие как NamingStrategy необходимо настроить с помощью класса конфигурации.

Поэтому рекомендуется удалить свойство и вместо этого установить его в коде на экземпляре Configuration, как это предложил Шив Рагуванши.

Ответ 2

Вы также можете установить конфигурацию.

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();
        }
    }
  }
}

Ответ 3

В вашей конфигурации нет ничего плохого. Просто, чтобы спящий режим с помощью объекта Configuration требовал установки некоторого свойства конфигурации в самом объекте конфигурации. Эта конфигурация, заданная с помощью свойств, будет проигнорирована.

Кроме того, загрузочный спящий режим с использованием объекта Configuration считается "устаревшим" способом (в соответствии с официальными документами спящего режима) и более новый способ рекомендуется загружать спящий режим, как показано ниже.

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

        StandardServiceRegistry standardRegistry = new StandardServiceRegistryBuilder()
                .configure() // using "hibernate.cfg.xml"
                .build();
        Metadata metadata = new MetadataSources(standardRegistry).buildMetadata();
        try (
                SessionFactory sessionFactory = metadata.getSessionFactoryBuilder().build();
                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();
            }
        }
    }

Это отобразит стратегию физического наименования, указанную как свойство hibernate в файле hibernate.cfg.xml.