问题如下:
public class TestPO{ private String code; private String name; public void setCode(String code){ this.code=code; } public String getCode(){ return this.code; } public void setName(String name){ this.name=name; } public String getName(){ return this.name; } // ................. }
对应的映射文件,TestPO.hbm.xml:
<hibernate-mapping> <class name="TestPO" table="TestPO"> <id name="code" type="java.lang.String"> <column name="code" length="12" /> <generator class="assigned" /> </id> <property name="name" type="java.lang.String"> <column name="name" length="30" /> </property> // ..................... </class> </hibernate-mapping>
由于历史数据的原因数据库code的设计为了char(12)
//..........获取Session TestPO testPO = new TestPO(); testPO.setCode("00000001");//注意:"00000001"没有12位 testPO.setName("name1"); session.saveOrUpdate(testPO); testPO.setName("name2"); session.saveOrUpdate(testPO);
提交事物后,发现数据库的name的值依然为"name1"
可能的原因:
当执行第二次保存的时候,相当于执行下面的语句:
update TestPO set name='name2' where code='00000001' ;
这条sql语句如果是用一般的客户端执行,也没有问题.
问题在于hibernate采用的预处理,即相当于采用下面的方式:
PreparedStatement prepareStatement = session.connection() .prepareStatement("update TestPO set name='name2' where code=? "); prepareStatement.setString(1, "K000003"); prepareStatement.execute();
解决的方法:
1、修改数据库,将code改为varchar2(12),如果数据库是遗留库,最好采用下面的方法
2、testPO.setCode("00000001 ");//用空格补齐12位
在一般的开发中可能比较难遇到这种问题,如果在开发中用到了遗留的数据库时,需要留意了。