关于hibernate的createSQLQuery会修改数据库数据的问题

时间:2021-06-29 07:28:15
        本人需要从oracle数据库的A表和B表中提取数据,A表在java中的对象为A类,B表在java中的对象为B类,代码如下:
String sql = “select a.*, b.* from a, b where a.xx = b.xx";
SQLQuery query = getSession().createSQLQuery(sql).addEntity(A.class).addEntity(B.class);
List<Object[]> list = query.list();
for(int j = 0; j < list.size(); j++) {
   A a = (A)list.get(j)[0];
   B b = (B)list.get(j)[1];
}
        查询完毕后,用for循环依次从list中提取出数据,根据要求,对某些字段的值进行修改,修改后,放入到另一个list中,然后传到前台显示。
        但是现在发现一个奇怪的问题,当我对字段进行修改后,没有执行任何和保存有关的命令(如save(),flush(),merge()什么的),数据库里面的内容却变更为我修改以后的内容了。
后来我做了一个实验,我在进行for循环的时候,不直接对查询出的对象进行修改,而是new一个新的对象,然后将查询出的对象的每一个属性依次赋值到那个新的对象中,然后再传到前台(也就是不对查询出的对象进行修改)。这样操作以后,数据库的数据就不再变化了。
        从以上的例子可以看出,hibernate好像每次在进行createSQLQuery操作时,会先将session中的对象进行一个类似保存的操作。不知道大家有没有遇到过这种情况,现在想问问大家:
        1、有谁比较了解hibernate,是不是像我猜测的那样。
        2、关于这种情况,有没有不用new一个新对象,然后一一赋值的办法。因为这种办法,将来新增加字段后,都必须要记得在这里的代码里添加对新字段的赋值代码,很麻烦。

16 个解决方案

#1


你可以配置一下hibernate的 打出sql 日志,看看 打出的sql

#2


事务的原因, 事务方法接收后session会自动flush, 会检测query出来的对象是否有修改,修改了便会更新到数据库.

#3


引用 2 楼 whos2002110 的回复:
事务的原因, 事务方法接收后session会自动flush, 会检测query出来的对象是否有修改,修改了便会更新到数据库.

 事务方法结束后

#4


引用 3 楼 whos2002110 的回复:
Quote: 引用 2 楼 whos2002110 的回复:

事务的原因, 事务方法接收后session会自动flush, 会检测query出来的对象是否有修改,修改了便会更新到数据库.

 事务方法结束后

如果这样的话,除了像我这样new一个对象,然后把原始内容一一赋值拷贝过来,还有没有别的办法呢?

#5


引用 4 楼 EmissaryWei 的回复:
Quote: 引用 3 楼 whos2002110 的回复:

Quote: 引用 2 楼 whos2002110 的回复:

事务的原因, 事务方法接收后session会自动flush, 会检测query出来的对象是否有修改,修改了便会更新到数据库.

 事务方法结束后

如果这样的话,除了像我这样new一个对象,然后把原始内容一一赋值拷贝过来,还有没有别的办法呢?


hibernate session的evict方法把query出来的对象在当前session中清除,就不会写到数据库了

#6


这是hibernate对象中的三种状态.  java中对象时引用类型,你查询出来此时状态是游离状态, 修改了之后,在事物提交后hibenrate就给你修改了. 又变成持久状态了   你新  new 的 是瞬时状态,  只有在调用save 后 再能变成 游离状态,  在事物提交的时候变成 持久状态

#7


关于这种情况, 可以自己使用  bytearrayoutputsteam    objectoutputstream        bytearrayinputstream  objectinputstream 这几个流进行序列化和反序列化,达到对象的克隆!   

#8


引用 6 楼 lwphk 的回复:
这是hibernate对象中的三种状态.  java中对象时引用类型,你查询出来此时状态是游离状态, 修改了之后,在事物提交后hibenrate就给你修改了. 又变成持久状态了   你新  new 的 是瞬时状态,  只有在调用save 后 再能变成 游离状态,  在事物提交的时候变成 持久状态

这几种状态我倒是知道,我只是没想到,我只是查询,没有专门提交,hibernate居然会自动给我提交掉

#9


引用 8 楼 EmissaryWei 的回复:
Quote: 引用 6 楼 lwphk 的回复:

这是hibernate对象中的三种状态.  java中对象时引用类型,你查询出来此时状态是游离状态, 修改了之后,在事物提交后hibenrate就给你修改了. 又变成持久状态了   你新  new 的 是瞬时状态,  只有在调用save 后 再能变成 游离状态,  在事物提交的时候变成 持久状态

这几种状态我倒是知道,我只是没想到,我只是查询,没有专门提交,hibernate居然会自动给我提交掉

你开启事物没有?   查询其实不用开启事物,或者就是开启只读事物

#10


事物的问题、Session session=  HibernateSessionFactory.getSession();获取session、不com就不会出现提交修改问题、LZ你要是真的纠结这个问题、先把spring中的SessionFactory的自动注入停下来、通过手动获取SessionFactory、就不会出现spring中事务和SessionFactory自动提交的效果了 关于hibernate的createSQLQuery会修改数据库数据的问题

#11


引用 9 楼 lwphk 的回复:
Quote: 引用 8 楼 EmissaryWei 的回复:

Quote: 引用 6 楼 lwphk 的回复:

这是hibernate对象中的三种状态.  java中对象时引用类型,你查询出来此时状态是游离状态, 修改了之后,在事物提交后hibenrate就给你修改了. 又变成持久状态了   你新  new 的 是瞬时状态,  只有在调用save 后 再能变成 游离状态,  在事物提交的时候变成 持久状态

这几种状态我倒是知道,我只是没想到,我只是查询,没有专门提交,hibernate居然会自动给我提交掉

你开启事物没有?   查询其实不用开启事物,或者就是开启只读事物

我对于hibernate的配置文件不太熟徐,如何看配置事务?在哪个xml文件中,关键字是什么?开启只读事务的关键是什么?谢谢了?

#12


引用 10 楼 ch1240249252 的回复:
事物的问题、Session session=  HibernateSessionFactory.getSession();获取session、不com就不会出现提交修改问题、LZ你要是真的纠结这个问题、先把spring中的SessionFactory的自动注入停下来、通过手动获取SessionFactory、就不会出现spring中事务和SessionFactory自动提交的效果了 关于hibernate的createSQLQuery会修改数据库数据的问题

不com是什么意思?

#13


引用 11 楼 EmissaryWei 的回复:
Quote: 引用 9 楼 lwphk 的回复:

Quote: 引用 8 楼 EmissaryWei 的回复:

Quote: 引用 6 楼 lwphk 的回复:

这是hibernate对象中的三种状态.  java中对象时引用类型,你查询出来此时状态是游离状态, 修改了之后,在事物提交后hibenrate就给你修改了. 又变成持久状态了   你新  new 的 是瞬时状态,  只有在调用save 后 再能变成 游离状态,  在事物提交的时候变成 持久状态

这几种状态我倒是知道,我只是没想到,我只是查询,没有专门提交,hibernate居然会自动给我提交掉

你开启事物没有?   查询其实不用开启事物,或者就是开启只读事物

我对于hibernate的配置文件不太熟徐,如何看配置事务?在哪个xml文件中,关键字是什么?开启只读事务的关键是什么?谢谢了?

用spring没有??? 百度下 多的很

#14


引用 12 楼 EmissaryWei 的回复:
Quote: 引用 10 楼 ch1240249252 的回复:

事物的问题、Session session=  HibernateSessionFactory.getSession();获取session、不com就不会出现提交修改问题、LZ你要是真的纠结这个问题、先把spring中的SessionFactory的自动注入停下来、通过手动获取SessionFactory、就不会出现spring中事务和SessionFactory自动提交的效果了 关于hibernate的createSQLQuery会修改数据库数据的问题

不com是什么意思?

提交
下面举一个查询的例子、修改跟他一样、不提交怎么可能
public List<Tbl2ShopTrade> findJy() {
// TODO Auto-generated method stub
List list =new ArrayList();
Session session=  HibernateSessionFactory.getSession();
try {
SessionFactory sf = HibernateSessionFactory.getSessionFactory();
String Hql = "from 表名";
Query query = session.createQuery(Hql);
list = query.list();

session.beginTransaction().commit();//我就是提交、不打我是修改不了数据库的
} catch (Exception e) {

session.beginTransaction().rollback();
}finally{
HibernateSessionFactory.closeSession();
}
return list;
}
你不提交
也就是这段session.beginTransaction().commit();代码、不打的话绝对不会出现修改数据库的情况

#15


上面那个SessionFactory是自己获取的、你要是用的SSH框架、Spring会自动注入SessionFactory和事务、所以会出现自动提交的问题、你把spring中的SessionFactory关了、自己获取

#16


检查下你的spring里面的配置。如果没有执行其它的添加或者修改。只能是你配置的问题。或者你可以调试下。打印出你的sql语句。这些都是小问题。和是否重新实例化无关。

#1


你可以配置一下hibernate的 打出sql 日志,看看 打出的sql

#2


事务的原因, 事务方法接收后session会自动flush, 会检测query出来的对象是否有修改,修改了便会更新到数据库.

#3


引用 2 楼 whos2002110 的回复:
事务的原因, 事务方法接收后session会自动flush, 会检测query出来的对象是否有修改,修改了便会更新到数据库.

 事务方法结束后

#4


引用 3 楼 whos2002110 的回复:
Quote: 引用 2 楼 whos2002110 的回复:

事务的原因, 事务方法接收后session会自动flush, 会检测query出来的对象是否有修改,修改了便会更新到数据库.

 事务方法结束后

如果这样的话,除了像我这样new一个对象,然后把原始内容一一赋值拷贝过来,还有没有别的办法呢?

#5


引用 4 楼 EmissaryWei 的回复:
Quote: 引用 3 楼 whos2002110 的回复:

Quote: 引用 2 楼 whos2002110 的回复:

事务的原因, 事务方法接收后session会自动flush, 会检测query出来的对象是否有修改,修改了便会更新到数据库.

 事务方法结束后

如果这样的话,除了像我这样new一个对象,然后把原始内容一一赋值拷贝过来,还有没有别的办法呢?


hibernate session的evict方法把query出来的对象在当前session中清除,就不会写到数据库了

#6


这是hibernate对象中的三种状态.  java中对象时引用类型,你查询出来此时状态是游离状态, 修改了之后,在事物提交后hibenrate就给你修改了. 又变成持久状态了   你新  new 的 是瞬时状态,  只有在调用save 后 再能变成 游离状态,  在事物提交的时候变成 持久状态

#7


关于这种情况, 可以自己使用  bytearrayoutputsteam    objectoutputstream        bytearrayinputstream  objectinputstream 这几个流进行序列化和反序列化,达到对象的克隆!   

#8


引用 6 楼 lwphk 的回复:
这是hibernate对象中的三种状态.  java中对象时引用类型,你查询出来此时状态是游离状态, 修改了之后,在事物提交后hibenrate就给你修改了. 又变成持久状态了   你新  new 的 是瞬时状态,  只有在调用save 后 再能变成 游离状态,  在事物提交的时候变成 持久状态

这几种状态我倒是知道,我只是没想到,我只是查询,没有专门提交,hibernate居然会自动给我提交掉

#9


引用 8 楼 EmissaryWei 的回复:
Quote: 引用 6 楼 lwphk 的回复:

这是hibernate对象中的三种状态.  java中对象时引用类型,你查询出来此时状态是游离状态, 修改了之后,在事物提交后hibenrate就给你修改了. 又变成持久状态了   你新  new 的 是瞬时状态,  只有在调用save 后 再能变成 游离状态,  在事物提交的时候变成 持久状态

这几种状态我倒是知道,我只是没想到,我只是查询,没有专门提交,hibernate居然会自动给我提交掉

你开启事物没有?   查询其实不用开启事物,或者就是开启只读事物

#10


事物的问题、Session session=  HibernateSessionFactory.getSession();获取session、不com就不会出现提交修改问题、LZ你要是真的纠结这个问题、先把spring中的SessionFactory的自动注入停下来、通过手动获取SessionFactory、就不会出现spring中事务和SessionFactory自动提交的效果了 关于hibernate的createSQLQuery会修改数据库数据的问题

#11


引用 9 楼 lwphk 的回复:
Quote: 引用 8 楼 EmissaryWei 的回复:

Quote: 引用 6 楼 lwphk 的回复:

这是hibernate对象中的三种状态.  java中对象时引用类型,你查询出来此时状态是游离状态, 修改了之后,在事物提交后hibenrate就给你修改了. 又变成持久状态了   你新  new 的 是瞬时状态,  只有在调用save 后 再能变成 游离状态,  在事物提交的时候变成 持久状态

这几种状态我倒是知道,我只是没想到,我只是查询,没有专门提交,hibernate居然会自动给我提交掉

你开启事物没有?   查询其实不用开启事物,或者就是开启只读事物

我对于hibernate的配置文件不太熟徐,如何看配置事务?在哪个xml文件中,关键字是什么?开启只读事务的关键是什么?谢谢了?

#12


引用 10 楼 ch1240249252 的回复:
事物的问题、Session session=  HibernateSessionFactory.getSession();获取session、不com就不会出现提交修改问题、LZ你要是真的纠结这个问题、先把spring中的SessionFactory的自动注入停下来、通过手动获取SessionFactory、就不会出现spring中事务和SessionFactory自动提交的效果了 关于hibernate的createSQLQuery会修改数据库数据的问题

不com是什么意思?

#13


引用 11 楼 EmissaryWei 的回复:
Quote: 引用 9 楼 lwphk 的回复:

Quote: 引用 8 楼 EmissaryWei 的回复:

Quote: 引用 6 楼 lwphk 的回复:

这是hibernate对象中的三种状态.  java中对象时引用类型,你查询出来此时状态是游离状态, 修改了之后,在事物提交后hibenrate就给你修改了. 又变成持久状态了   你新  new 的 是瞬时状态,  只有在调用save 后 再能变成 游离状态,  在事物提交的时候变成 持久状态

这几种状态我倒是知道,我只是没想到,我只是查询,没有专门提交,hibernate居然会自动给我提交掉

你开启事物没有?   查询其实不用开启事物,或者就是开启只读事物

我对于hibernate的配置文件不太熟徐,如何看配置事务?在哪个xml文件中,关键字是什么?开启只读事务的关键是什么?谢谢了?

用spring没有??? 百度下 多的很

#14


引用 12 楼 EmissaryWei 的回复:
Quote: 引用 10 楼 ch1240249252 的回复:

事物的问题、Session session=  HibernateSessionFactory.getSession();获取session、不com就不会出现提交修改问题、LZ你要是真的纠结这个问题、先把spring中的SessionFactory的自动注入停下来、通过手动获取SessionFactory、就不会出现spring中事务和SessionFactory自动提交的效果了 关于hibernate的createSQLQuery会修改数据库数据的问题

不com是什么意思?

提交
下面举一个查询的例子、修改跟他一样、不提交怎么可能
public List<Tbl2ShopTrade> findJy() {
// TODO Auto-generated method stub
List list =new ArrayList();
Session session=  HibernateSessionFactory.getSession();
try {
SessionFactory sf = HibernateSessionFactory.getSessionFactory();
String Hql = "from 表名";
Query query = session.createQuery(Hql);
list = query.list();

session.beginTransaction().commit();//我就是提交、不打我是修改不了数据库的
} catch (Exception e) {

session.beginTransaction().rollback();
}finally{
HibernateSessionFactory.closeSession();
}
return list;
}
你不提交
也就是这段session.beginTransaction().commit();代码、不打的话绝对不会出现修改数据库的情况

#15


上面那个SessionFactory是自己获取的、你要是用的SSH框架、Spring会自动注入SessionFactory和事务、所以会出现自动提交的问题、你把spring中的SessionFactory关了、自己获取

#16


检查下你的spring里面的配置。如果没有执行其它的添加或者修改。只能是你配置的问题。或者你可以调试下。打印出你的sql语句。这些都是小问题。和是否重新实例化无关。