Jpa+Hibernate开发销售应用出现org.hibernate.MappingException如何解决
异常原因
Hibernate 本身默认没有适配 javafx.scene.image.Image 类型的持久化映射规则,无法直接将该类型的字段映射为数据库表的字段,因此会抛出类型识别失败的映射异常。
解决方案
推荐优先使用以下两种方案解决:
方案一:存储图片路径(优先推荐)
不直接存储图片本身,只将图片的本地存储路径、或者云存储URL以字符串形式存入数据库,业务层需要使用Image对象时再通过路径读取转换即可,该方案不会占用数据库大量存储空间,查询性能更高。
修改后的实体类代码参考:
@Entity @Table(name="PRODUCT", schema = "ROOT" ) public class Product { private SimpleIntegerProperty productId; private SimpleStringProperty productName; // 替换原Image类型字段,存储图片路径 private String picturePath; private Date addingDate; public Product() { this.productId = new SimpleIntegerProperty(); this.productName = new SimpleStringProperty(); } @Column(name= "picture") public String getPicturePath() { return this.picturePath; } public void setPicturePath(String picturePath) { this.picturePath = picturePath; } // 需要使用Image对象时调用该方法转换即可 public Image getPicture() { if(this.picturePath == null) { return null; } try { return new Image(new FileInputStream(picturePath)); } catch (FileNotFoundException e) { e.printStackTrace(); return null; } } }
方案二:存储图片二进制内容到数据库
如果业务要求必须将图片存入数据库,可以将实体字段改为byte[]类型,搭配@Lob注解映射为数据库的大二进制字段,自行实现byte[]和Image的互转逻辑。
修改后的实体类代码参考:
@Entity @Table(name="PRODUCT", schema = "ROOT" ) public class Product { private SimpleIntegerProperty productId; private SimpleStringProperty productName; // 用byte[]存储二进制内容,指定字段类型为BLOB @Lob @Column(name= "picture", columnDefinition = "BLOB") private byte[] pictureBytes; private Date addingDate; public Product() { this.productId = new SimpleIntegerProperty(); this.productName = new SimpleStringProperty(); } public byte[] getPictureBytes() { return pictureBytes; } public void setPictureBytes(byte[] pictureBytes) { this.pictureBytes = pictureBytes; } // Image和byte[]互转方法 public Image getPicture() { if(this.pictureBytes == null) { return null; } return new Image(new ByteArrayInputStream(pictureBytes)); } public void setPicture(Image picture) throws IOException { BufferedImage bImage = SwingFXUtils.fromFXImage(picture, null); ByteArrayOutputStream baos = new ByteArrayOutputStream(); ImageIO.write(bImage, "png", baos); this.pictureBytes = baos.toByteArray(); } }
注意事项
- 方案二需要依赖
SwingFXUtils完成JavaFX的Image对象和AWT的BufferedImage对象的转换,写入大体积图片会导致数据库存储空间占用快速上升,查询效率降低,非必要不建议使用。
内容的提问来源于stack exchange,提问作者Nacira
相关产品推荐
相关产品推荐

