Inconsistent definition of string length between Java strings String.substring () and Oracle 11g VARCHAR2

I installed my database with the following table:

CREATE TABLE t_audit_log
(
  description VARCHAR2 (2500)
);

In a Java application that uses it, I use Hibernate to map the data class to it and to make sure that I will not generate SQLExceptions, I put this truncation algorithm in the getter property:

private static final int MAX_STRING_LEN_2500 = 2499;

public void setDescription(final String newDescription) {
    if (newDescription != null
        && newDescription.length() > MAX_STRING_LEN_2500) {
        description = newDescription.substring(0, MAX_STRING_LEN_2500);
    } else {
        description = newDescription;
    }
}

In thousands of audit log entries, this worked fine - until today. I found this in the logs:

Nov 09, 2015 7:54:40 AM org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions
WARN: SQL Error: 12899, SQLState: 72000
Nov 09, 2015 7:54:40 AM org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions
ERROR: ORA-12899: value too large for column "BLABLA"."T_AUDIT_LOG"."DESCRIPTION" 
    (actual: 2501, maximum: 2500)

Why did you substring()leave an extra character in the value?

+4
source share
2 answers

, " " ( NLS_LENGTH_SEMANTICS), , 2500 , 2500 . , UTF-8 - 2498 ASCII 1 U + 20A0 ( ), 2501 , 2499 .

Java length() substring() UTF-16, " ". ( , , UTF-16, .)

, , - , , Java.

+9

Oracle NLS_LENGTH_SEMANTICS, , BYTE CHAR, BYTE. ,

CREATE TABLE t_audit_log
(
  description VARCHAR2 (2500 char)
);

.


Oracle:

NLS_LENGTH_SEMANTICS VARCHAR2 CHAR , PL/SQL , . BYTE CHAR , .

+7

Source: https://habr.com/ru/post/1615074/


All Articles