Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/65.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在Hibernate中正确处理长数据_Java_Mysql_Hibernate - Fatal编程技术网

Java 在Hibernate中正确处理长数据

Java 在Hibernate中正确处理长数据,java,mysql,hibernate,Java,Mysql,Hibernate,我在hibernate中遇到了一个数据太大的问题。就是- 原因:java.sql.BatchUpdateException:数据截断:第1行“FBZipLoc”列的数据太长 位于com.mysql.jdbc.PreparedStatement.executeBatchSerially(PreparedStatement.java:1527) 位于com.mysql.jdbc.PreparedStatement.executeBatch(PreparedStatement.java:1065) 位

我在hibernate中遇到了一个数据太大的问题。就是-

原因:java.sql.BatchUpdateException:数据截断:第1行“FBZipLoc”列的数据太长 位于com.mysql.jdbc.PreparedStatement.executeBatchSerially(PreparedStatement.java:1527) 位于com.mysql.jdbc.PreparedStatement.executeBatch(PreparedStatement.java:1065) 位于org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:58) 位于org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:195) ... 还有12个

是否可以自动截断所有字段的数据。 或者其他任何处理这个问题的方法。
但我不想检查所有字段的数据长度,因为我有上千个字段。

据我所知,Hibernate或MySQL真的无法在不添加逻辑处理的情况下自动截断字符串。我之所以认为这样的东西不存在,是因为我永远不希望我要求插入到数据库中的内容与实际插入的内容不同

我想你唯一的选择是

  • 更改列定义。将其设置为更大的varchar字段,甚至可以设置为文本字段。不要花时间构建一个神奇的工具,只要更改列定义,几次单击就可以解决这个问题。我建议你这样做

  • 我可以看到您使用某种方面来拦截设置器,然后调整字符串的大小(如果大于x长度)。这将是在代码中处理它的最快方法。如果更改数据库不是一个选项,而您有数千个字段,这将是我的下一个选择

  • 构建一个字符串util类,该类可以重新调整字符串的大小

    setText(String val){this.text=StringUtil.truncate(val,size);}

  • [更新] 由于您无法真正更新数据库,我建议您使用一个方面来拦截字符串设置器并检查其长度,它可能是这样的(语法可能已关闭,我没有对此进行测试)

    私有静态最终最大字符串大小=255;
    @大约(“执行(*your.package.*.set*(..)&&args(java.lang.String)”)
    公共无效检查设置器(最终处理接合点pjp)
    扔掉的{
    对象[]args=pjp.getArgs();
    对于(int i=0;i最大字符串大小{
    args[i]=((字符串)args[i])。子字符串(0,字符串的最大大小);
    }
    }
    pjp.继续(args);
    }
    
    此外,如果某个层必须在每次插入时根据表中的所有数据检查定义的列大小,则会有一些额外的开销。

    您可以使用它。它将允许您更改对象状态
    就在你保存它之前。您可以根据保存的特定列或特定类型轻松地修剪字符串。

    您可以配置MySQL以截断数据,如果这是您真正想要的:

    如果未启用严格SQL模式,并且为超过列最大长度的CHAR或VARCHAR列指定了一个值,则该值将被截断以适合该列,并生成警告。对于非空格字符的截断,可以使用严格的SQL模式导致出现错误(而不是警告)并禁止插入值。见第5.1.7节


    但是,这对于生产数据库是不可取的。

    您必须1。手动编写一个函数,在保存数据之前检查长度并截断数据(如果可能)。2.在DB中展开列空间。如果有大量的列,则使用一个方面来截取,而字段SI有数千个字段,所以我不能编写一个函数并从每个字段调用。我的项目几乎完成了95%个,我有98个表,有120到150个字段,所以我不能改变我的BD或列属性。考虑一个方面,然后截取和截断。串。它将比StringUtil更简单,代码更改也更少。在这种情况下,Hibernate拦截器可能比AspectJ拦截器更好。@Alex:同意(+1)。我忘了股票拦截。这将是一个更好的选择。我没有使用Jboss,我只使用了一个简单的hibernate3.jar和hibernate。它与Jboss无关。这是在jboss网站上托管的Hibernate文档。我不理解你的上一条评论。请澄清。@AlexGitelman让我们
    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);
    }