使用的数据库是:Oracle9i
根据网上的方法,存储Blob类型数据分为三步:1、给记录的Blob字段赋一个空值,并存入数据库;2、以更新锁定的方法从数据库中获取该记录,从而Blob字段的游标;3、将文件写入Blob,更新数据库
执行到第二步时,以更新锁定的方式读取记录时报错:
(0 ms) [http-8080-3] WARN : org.hibernate.util.JDBCExceptionReporter#logExceptions : SQL Error: 1002, SQLState: 72000
(18 ms) [http-8080-3] ERROR: org.hibernate.util.JDBCExceptionReporter#logExceptions : ORA-01002: 读取违反顺序
网上的方法主要是说需要将自动提交设为false,我这么做了还是不行,代码如下,请各位高手帮忙看看问题出在哪里,多谢了!
@RequestMapping(params = "method=image")
@ResponseBody
    public void uploadImage(@RequestParam(value = "imageFile") MultipartFile file,
     HttpServletRequest request, HttpServletResponse response){
JSONObject jsonObject = new JSONObject();  
//Map<String, Object> modelMap = new HashMap<String, Object>();

//Session session = (Session) sessionFactory.openSession();
//取消自动提交
try {
SessionFactoryUtils.getDataSource(getSessionFactory()).getConnection().setAutoCommit(false);
} catch (SQLException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
}
//查询待修改的记录
String objcode = request.getParameter("objcode");
AbstractTab abstractTab = deviceManager.getTabByTabName("Camera_Info_Tab");
Camera_Info_Tab cameraInfoTab = (Camera_Info_Tab)deviceManager.get(abstractTab.getClass(), objcode);
//给Blob赋空值,使其有游标
Blob blob = cameraInfoTab.getImage1();

byte[] buffer = new byte[1];   
buffer[0] = 1;   
cameraInfoTab.setImage1(Hibernate.createBlob(buffer));
//更新记录
deviceManager.update(cameraInfoTab);
//以for update方式再次获取该条记录
//此处报错,读取违反顺序
cameraInfoTab = (Camera_Info_Tab)deviceManager.getWithLock(abstractTab.getClass(), objcode, LockMode.UPGRADE);
//文件内容存入Blob中
blob = cameraInfoTab.getImage1();
OutputStream  out = null;
SerializableBlob serializableBlob = (SerializableBlob)blob;
BLOB blob2 = (BLOB)serializableBlob.getWrappedBlob();
try {
out   =  blob2.getBinaryOutputStream();

} catch (SQLException e) {
jsonObject.put("result", "error");
e.printStackTrace();

byte[] data = null;
try {
data = file.getBytes();
} catch (IOException e1) {
jsonObject.put("result", "error");
e1.printStackTrace();
}

try {
out.write(data);
} catch (IOException e) {
jsonObject.put("result", "error");
e.printStackTrace();
}
  
         try {
out.close();
         } catch (IOException e) {
          jsonObject.put("result", "error");
e.printStackTrace();
         }
 //再次更新
         deviceManager.update(cameraInfoTab);
 
//return modelMap;
}hibernatespringblob

解决方案 »

  1.   

    配置文件里边没有设置自动提交,但是我在
    SessionFactoryUtils.getDataSource(getSessionFactory()).getConnection().setAutoCommit(false);
    前后分别输出了:
    SessionFactoryUtils.getDataSource(getSessionFactory()).getConnection().getAutoCommit();
    在设置为false之前,是true,设置之后输出是false。
    网上说是spring管理hibernate时有相关的设置,所以默认是true。
      

  2.   

    搞定了,但是没有用这套方法了,换成使用Spring提供的Lob数据处理方法,将Blob持久化为byte[],在使用Spring提供的oracleLobHandler来解决。不过好像对于特别大的数据(上百兆)的支持不太好,不过这么大的数据一般也不会直接存在数据库中。