如何更新数据库中的LOB文件?解决Hibernate属性访问异常
问题原因
异常核心是类型不匹配:你的Users实体类中image字段定义为String类型,但更新时试图将MultipartFile(最终被转换为JDBC的Blob对象)赋值给该字段,Hibernate无法完成跨类型转换,因此抛出属性访问异常。
另外你的Controller代码里直接调用myUpdateData.setImage(file);,这在编译阶段就应该报错(setImage接收String而非MultipartFile),运行时的根源还是二进制数据与String类型的不兼容。
解决方案
提供两种可行修复方案,按需选择:
方案一:转Base64字符串存储(保留String字段)
适合需要直接在前端展示图片的场景,无需额外转换:
- 修改Controller层:将
MultipartFile转为Base64字符串后赋值:
@RequestMapping("/UpdateData") @ResponseBody public String Updatedata(@RequestParam("id")int id,@RequestParam("username")String username,@RequestParam("file")MultipartFile file) { Users myUpdateData = service.getdataByid(id); myUpdateData.setUsername(username); if (!file.isEmpty()) { try { byte[] bytes = file.getBytes(); String base64Image = Base64.getEncoder().encodeToString(bytes); myUpdateData.setImage(base64Image); } catch (IOException e) { e.printStackTrace(); return "fail"; } } service.Updatedata(myUpdateData); return "success"; }
- Users实体类无需修改,保持
image为String类型即可。
方案二:改用byte[]存储二进制数据(适配Blob字段)
更符合数据库BLOB字段设计,存储效率更高:
- 修改Users实体类:将
image字段改为byte[],同步更新getter/setter:
@Entity public class Users { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private int id; private String username; @Lob @Column(columnDefinition = "MEDIUMBLOB") private byte[] image; // 字段类型改为byte[] public byte[] getImage() { return image; } public void setImage(byte[] image) { this.image = image; } // 其他getter/setter保持不变 }
- 修改Controller层:将
MultipartFile转为字节数组后赋值:
@RequestMapping("/UpdateData") @ResponseBody public String Updatedata(@RequestParam("id")int id,@RequestParam("username")String username,@RequestParam("file")MultipartFile file) { Users myUpdateData = service.getdataByid(id); myUpdateData.setUsername(username); if (!file.isEmpty()) { try { myUpdateData.setImage(file.getBytes()); } catch (IOException e) { e.printStackTrace(); return "fail"; } } service.Updatedata(myUpdateData); return "success"; }
额外优化建议
你的Service层存在重复查询:Controller已通过service.getdataByid(id)获取实体,Service里又调用repo.findByid(mod.getId())查询一次,可简化为:
public Users Updatedata(Users mod) { // 直接使用传入的持久化对象,无需重复查询 return repo.save(mod); }
减少数据库查询的同时,避免对象状态不一致问题。
内容的提问来源于stack exchange,提问作者Benjie Alcontin
相关产品推荐
相关产品推荐

