我正在学习Java和Hibernate。现在,我无法理解如何使用自定义物理命名策略:虽然toPhysicalTableName
对象确实已实例化,但toPhysicalColumnName
或@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
方法从未被调用 - 不是我至少可以看到调试器。
版本:Java 1.8,Hibernate 5.2.10.Final,在macOS 10.12上。
这是一个最小的项目:
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 |
+----+-----------+-----------------------+---------+
我希望:
c2 = Comment.arel_table.alias
s1 = Comment.arel_table.
project(c2[:user_id], c2[:created_at].maximum.as('max_created_at')).
from(c2).group('user_id').as('s1')
puts s1.to_sql
# (SELECT "comments_2"."user_id", MAX("comments_2"."created_at") AS max_created_at
# FROM "comments" "comments_2" GROUP BY user_id) s1
我在这里做错了什么?
答案 0 :(得分:3)
这个文档没有很好记录,但遗憾的是Hibernate似乎不支持在hibernate.cfg.xml中设置的特定属性。引用a very old Hibernate forum post:
您只能在给定Environment.java类的属性中设置 hibernate.properties或hibernate.cfg.xml。其余的属性如 必须使用Configuration类配置NamingStrategy。
所以建议删除属性,而不是像Shiv Raghuwanshi所建议的那样在Configuration实例的代码中设置它。
答案 1 :(得分: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();
}
}
}
}
答案 2 :(得分:1)
您的配置没有任何问题。只是使用Configuration
对象引导hibernate需要您在配置对象本身上设置配置属性的某些。通过属性指定的这些配置将被忽略。
此外,使用Configuration对象引导hibernate被视为“遗留”方式(as per official hibernate docs),建议newer way引导hibernate,如下所示。
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属性的物理命名策略。