最近在学习hibernate的文档,按照它提供的例子写了一个写入通过OR映射保存数据并用hql查询的测试程序,发现了一个奇怪的问题:
就是插入的数据再次查询就不见了,插入数据的程序执行后可以在数据库中查找到,但是执行一次hql查询后就不见了
这是插入数据的程序:
Session session = HibernateUtil.getSessionFactory().getCurrentSession();
session.beginTransaction();
Person p = new Person();
p.setName("zxy");
session.save(p);
session.getTransaction().commit();
这是查询数据的程序:
Session session = HibernateUtil.getSessionFactory().getCurrentSession();
System.out.println("list: "+session);
session.beginTransaction();
List<Person> persons = session.createQuery("from Person ").list();
session.getTransaction().commit();
我的分析思路是这样的,因为我用的是oracle数据库,所以我确定这些数据确实是已经提交了的。我就猜想可能是hibernate的某个参数配置错误了,但是我对hibernate不熟悉,不知道具体的配置位置,只好通过排除法一段一段debug代码来确定hibernate是在什么时候删除了我创建的数据。
我发现在创建SessionFactory后数据就消失了,跟到org.hibernate.impl.SessionFactoryImpl中的371行时发现有这样一个判断
if ( settings.isAutoCreateSchema() ) {
new SchemaExport( cfg, settings ).create( false, true );
}
然后又看到了SchemaExport的构造方法
public SchemaExport(Configuration cfg, Settings settings) throws HibernateException {
dialect = settings.getDialect();
connectionHelper = new SuppliedConnectionProviderConnectionHelper( settings.getConnectionProvider() );
dropSQL = cfg.generateDropSchemaScript( dialect );
createSQL = cfg.generateSchemaCreationScript( dialect );
sqlStatementLogger = settings.getSqlStatementLogger();
formatter = ( sqlStatementLogger.isFormatSql() ? FormatStyle.DDL : FormatStyle.NONE ).getFormatter();
importFiles = settings.getImportFiles() != null ? settings.getImportFiles() : DEFAULT_IMPORT_FILE;
}
真相在这里大白了,这里生成的dropSQL会删除我OR映射创建的所有表,然后在重新创建一次。
后来我在网上查了查,原来是我hibernate.cfg.xml中一个配置项配错了
<property name="hbm2ddl.auto">create</property>
这里改成none就好了。
顺便记录下hibernate.cfg.xml中属性 hbm2ddl.auto的值含义:
validate 加载hibernate时,验证创建数据库表结构
create 每次加载hibernate,重新创建数据库表结构,这就是导致数据库表数据丢失的原因。
create-drop 加载hibernate时创建,退出时删除表结构
update 加载hibernate自动更新数据库结构
建议设置成none,也就是什么也不做。
留个脚印,这个问题烦恼了我一天,留待以后参考。