正确处理Hibernate中的长数据
我在hibernate中遇到数据太大的问题。 那是-
引起:java.sql.BatchUpdateException:数据截断:com.mysql.jdbc.PreparedStatement.executeBatch中com.mysql.jdbc.PreparedStatement.executeBatchSerially(PreparedStatement.java:1527)第1行第’列FBZipLoc’的数据太长(PreparedStatement.java:1065)org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:58)org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:195)… 12更多
是否可以自动截断所有字段的数据。 或任何其他方式来处理这个问题。 但我不想检查所有字段的数据长度,因为我有超过一千个字段。
据我所知,Hibernate或MySQL实际上没有办法自动截断字符串,而无需添加逻辑来处理这个问题。 我之所以认为这样的东西不存在,是因为我永远不会想要我插入数据库的内容与实际插入的内容不同。
我认为你唯一的选择是……
-
更改列定义。 使其成为更大的varchar字段或甚至是文本字段。 当只是更改列定义时,不要花时间构建一个神奇的工具,只需点击几下即可解决此问题。 我建议这样做!
-
我可以看到你使用某种方面拦截 setter,然后调整字符串的大小,如果它大于x长度。 这将是您在代码中处理它的最快捷的原因。 如果更改数据库不是一个选项,并且您有数千个字段,那么这将是我的下一个选择。
-
构建一个String util类,可以重新调整字符串的大小……
setText(String val){this.text = StringUtil.truncate(val,size);}
[更新]由于你无法真正更新数据库,我建议一个方面拦截字符串setter并检查它们的长度它可能看起来像这样(语法可能关闭,我没有测试这个)…
private static final MAX_SIZE_OF_STRINGS = 255; @Around("execution(* your.package.*.set*(..)) && args(java.lang.String)") public void checkAroundSetter(final ProceedingJoinPoint pjp) throws Throwable { Object[] args = pjp.getArgs(); for (int i = 0; i < args.length; i++) { if (args[i] instanceof String && ((String) args[i]).size() > MAX_SIZE_OF_STRINGS) { args[i] = ((String)args[i]).subString(0,MAX_SIZE_OF_STRINGS) ; } } pjp.proceed(args); }
此外,如果某个层必须针对每个插入中进入表中的所有数据检查定义的列大小,则会有一些额外的开销。
你可以使用Hibernate拦截器 。 它允许您在保存之前更改对象状态。 您可以根据保存的特定列或特定类型轻松修剪字符串。
您可以配置MySQL以截断数据,如果这是您真正想要的:
如果未启用严格SQL模式,并且您为CHAR或VARCHAR列分配的值超出了列的最大长度,则会截断该值以适应并生成警告。 对于非空格字符的截断,可以导致发生错误(而不是警告),并通过使用严格的SQL模式来禁止插入值。 请参见第5.1.7节“服务器SQL模式” 。
但是,这不适用于生产数据库。
- 使用@Id和@EmbeddedId作为复合键的区别
- JPA 2.0 / Hibernate:为什么LAZY使用“@OneToOne”开箱即用?
- Hibernate将对象保存到多个会话
- 使用Oracle 10g时,Hibernate对浮点列的模式validation的已知问题有哪些最佳解决方法?
- Hibernate 4.2.2从未知长度的输入流创建blob
- Hibernatevalidation – 仅validation对象是否为空
- 适用于Hibernate pojo中@lob的hibernate映射。 我们正在使用hibernate映射。 你能告诉我@lob注释的等价物吗?
- JDBC批处理操作的理解
- Hibernate hbm2ddl.auto默认值