Hibernate执行查询代码却清空MySQL数据,无异常原因排查
问题:Hibernate执行查询后数据库数据被清空?
我在已有数据的MySQL数据库中调用下述代码,结果数据库内所有数据被清空,返回的funds列表为空,程序执行过程中未出现任何错误或异常。请问该问题的原因是什么?
Session session = factory.openSession(); Transaction tx = null; List<Fund> funds = new ArrayList(); try { tx = session.beginTransaction(); String hql = "FROM Fund";// name of class, not a column Query query = session.createQuery(hql); funds = query.getResultList(); tx.commit(); } catch (HibernateException e) { if (tx != null) tx.rollback(); e.printStackTrace(); } finally { session.close(); return funds; }
原因分析
我来帮你梳理几个实际开发中最常碰到的原因:
- 自动DDL配置是头号嫌疑:这是最常见的坑!如果你的Hibernate配置里把
hibernate.hbm2ddl.auto设成了create或者create-drop,那每次SessionFactory初始化时,Hibernate都会先删掉对应的数据表,再重新创建一张空表。哪怕你只是执行查询操作,只要程序启动时触发了这个DDL逻辑,数据库里的旧数据就直接被清空了。你去检查下配置文件(不管是xml还是properties/yaml),有没有类似<property name="hibernate.hbm2ddl.auto">create</property>或者spring.jpa.hibernate.ddl-auto=create的配置?有的话改成update或者none就不会删表了。 - 排查隐藏的删除逻辑:你贴的这段查询代码本身没问题,但要确认这段代码是不是嵌套在某个大事务里?比如之前有批量删除操作没提交,最后和这个查询的事务一起提交了?不过你说没报错,这种可能性相对小,但还是要排查下代码上下文。
- 实体映射与数据库表不匹配:如果你的
Fund实体类的表名、主键映射和数据库实际的表对不上,Hibernate可能会认为对应的表不存在,然后根据DDL配置新建一张空表,你查询的是新表所以返回空,而旧表可能被误删了?你可以看看Hibernate的日志,有没有输出create table之类的语句,就能确认是不是这个问题。 - 数据库层面的特殊情况:这个概率比较低,但也可以排查下——比如数据库用户有没有意外的删除权限,或者数据库里有没有触发器,当执行查询时触发了删除数据的逻辑?不过这种情况很少见,优先排查前面的Hibernate配置问题。
内容的提问来源于stack exchange,提问作者Krzysztof
相关产品推荐
相关产品推荐

