Правильная обработка длинных данных в спящем режиме

Я получаю слишком большие данные в спящем режиме. то есть -

Вызвано: java.sql.BatchUpdateException: Усечение данных: слишком длинны данные для столбца "FBZipLoc" в строке 1     at com.mysql.jdbc.PreparedStatement.executeBatchSerially(PreparedStatement.java:1527)     at com.mysql.jdbc.PreparedStatement.executeBatch(PreparedStatement.java:1065)     на org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:58)     at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:195)     ... еще 12

Возможно ли автоматическое усечение всех данных поля. или любым другим способом решения этой проблемы. но я не хочу проверять всю длину данных поля, потому что у меня больше тысячи полей.

Ответ 1

Из того, что я знаю, нет никакой возможности для Hibernate или MySQL автоматически обрезать строки без добавления в логику для обработки этого. Причина, по которой я бы поверила, что что-то вроде этого не существует, заключается в том, что я никогда не хочу, чтобы то, что я попросил вставить в базу данных, отличалось от того, что действительно было вставлено.

Я думаю, что ваши единственные варианты...

  • Изменить определения столбцов. Сделать это большим полем varchar или, возможно, даже текстовым полем. Не тратьте время на создание волшебного инструмента, когда только изменение определения столбца исправит это за пару кликов. Я рекомендую сделать это!

  • Я мог видеть, что вы используете какой-то аспект для перехвата сеттеров, а затем корректируете размер строки, если она больше, чем длина x. Это было бы самым быстрым, почему бы это сделать в вашем коде. Если изменение БД не является вариантом, и у вас есть тысячи полей, это будет моим следующим выбором.

  • Создайте класс, который может изменить размер ваших строк...

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

[ОБНОВЛЕНИЕ] Поскольку вы не можете реально обновить базу данных, я бы рекомендовал аспект для перехвата String seters и проверить их длину, это может выглядеть так (синтаксис может быть выключен, и я не тестировал это)...

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);
}

Кроме того, будут некоторые дополнительные накладные расходы, если какой-либо уровень должен был проверить определенный размер столбца для всех данных, поступающих в таблицу на каждой вставке.

Ответ 2

Для этого вы можете использовать Hibernate interceptor. Это позволит вам изменить состояние объекта прямо перед тем, как вы его сохраните. Вы можете легко обрезать свои строки на основе определенных столбцов или конкретных типов, которые вы сохраняете.

Ответ 3

Вы можете настроить MySQL на усечение данных, если это вам действительно нужно:

Если строгий режим SQL не включен и вы присваиваете значение столбцу CHAR или VARCHAR, который превышает максимальную длину столбца, значение усекается, чтобы соответствовать, и генерируется предупреждение. Для усечения несовместимых символов вы можете вызвать ошибку (а не предупреждение) и подавить вставку значения с помощью строгого режима SQL. См. Раздел 5.1.7, "Режимы сервера SQL" .

Однако это нецелесообразно для производства db.