hibernate.cfg.xml中如何配置物理命名策略?

Posted

技术标签:

【中文标题】hibernate.cfg.xml中如何配置物理命名策略?【英文标题】:How to configure a physical naming strategy in hibernate.cfg.xml? 【发布时间】:2018-02-18 08:05:57 【问题描述】:

我正在学习 Java 和 Hibernate。现在,我很难理解如何使用自定义物理命名策略:虽然 PhysicalNamingStrategy 对象确实已实例化,但从未调用过 toPhysicalTableNametoPhysicalColumnName 方法——这不是我可以用调试器看到的,至少。

版本: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 |
+----+-----------+-----------------------+---------+

我在这里做错了什么?

【问题讨论】:

您使用的是哪个版本的 Hibernate? 编辑了我手头的尽可能多的细节。以后有小版本。 看来您的原始代码/配置应该可以工作。我假设您在 hibernate.cfg.xml 文件中仔细检查了 AllCapsPhysicalNamingStrategy 的完全限定路径是否正确。 @SteveChambers 我做到了。如果不是,hibernate 理所当然地抱怨AllCapsPhysicalNamingStrategy 不是PhysicalNamingStrategy 的实例。 【参考方案1】:

这没有很好的记录,但不幸的是,Hibernate 似乎不支持在 hibernate.cfg.xml 中设置的特定属性。引用a very old Hibernate forum post:

您只能在给定 Environment.java 类中设置属性 hibernate.properties 或 hibernate.cfg.xml。其余属性如 NamingStrategy 必须使用 Configuration 类进行配置。

因此建议删除该属性,而是按照 Shiv Raghuwanshi 的建议在 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();
        
    
  

【讨论】:

啊啊!这行得通,但是用.setProperty 替换.setPhysicalNamingStrategy 不行。但我也不能在那里设置我想要的任何东西。每当我设置一个不是 PhysicalNamingProperty 的类(在 XML 中或使用 setProperty)时,我都会得到 java.lang.ClassCastException: com.example.Cake cannot be cast to org.hibernate.boot.model.naming.PhysicalNamingStrategy【参考方案3】:

您的配置没有问题。只是使用Configuration 对象引导休眠需要您在配置对象本身上设置 一些 配置属性。这些通过属性指定的配置将被忽略。

此外,使用配置对象引导休眠被认为是“传统”方式(as per official hibernate docs),建议使用newer way 引导休眠,如下所示。

    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.cfg.xml 文件中指定为休眠属性的物理命名策略。

【讨论】:

以上是关于hibernate.cfg.xml中如何配置物理命名策略?的主要内容,如果未能解决你的问题,请参考以下文章

如何在hibernate.cfg.xml中的主配置文件中配置多个映射文件

如何使用 maven 配置 hibernate-tools 以生成 hibernate.cfg.xml、*.hbm.xml、POJO 和 DAO

hibernate.cfg.xml 中如何设置 hbm.xml 和 Annotations 的 mapping

如何使用 hibernate.properties 文件而不是 hibernate.cfg.xml

hibernate--hibernate.cfg.xml常用配置详解

配置NHibernate hibernate.cfg.xml文件以获得更多连接字符串