我有一个字段 id 定义如下。它是数据库中的 varbinary(16),当我通过 JPA 插入新记录时,我得到“com.mysql.jdbc.MysqlDataTruncation:数据截断:第 1 行的列“ID”的数据太长”。我做错了什么?
@Id
@Column(name="ID")
private UUID id;
A
UUID
是一个 128 位数字,由由连字符 ( '-'
) 分隔的五个十六进制数字组成的 utf8 字符串表示。
UUID()
返回的字符串的字符长度为'36'
。
因此,具有
'16'
长度的列定义是不够的。当这样定义时,您将收到上述错误。
mysql> create table tbl_so_q24028471_vb( v varbinary(16) );
Query OK, 0 rows affected (0.42 sec)
mysql> desc tbl_so_q24028471_vb;
+-------+---------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------------+------+-----+---------+-------+
| v | varbinary(16) | YES | | NULL | |
+-------+---------------+------+-----+---------+-------+
1 row in set (0.17 sec)
mysql> insert into tbl_so_q24028471_vb values( uuid() );
ERROR 1406 (22001): Data too long for column 'v' at row 1
更改列定义以适应更多长度和用途。
mysql> alter table tbl_so_q24028471_vb modify column v varbinary(36);
Query OK, 0 rows affected (0.86 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> insert into tbl_so_q24028471_vb values( uuid() );
Query OK, 1 row affected (0.08 sec)
mysql> select * from tbl_so_q24028471_vb;
+--------------------------------------+
| v |
+--------------------------------------+
| 630d3270-ebba-11e3-bd03-bc8556a95cc2 |
+--------------------------------------+
您尝试在 16 字节空间中存储 36 个字符的字符串。那是行不通的。
您需要获取 UUID 后面的位,这些位适合二进制 (16)。由于您使用的是 Java,因此您可以执行以下操作:
ByteBuffer bb = ByteBuffer.wrap(new byte[16]);
bb.putLong(uuid.getMostSignificantBits());
bb.putLong(uuid.getLeastSignificantBits());
return bb.array();
然后将生成的字节数组插入到数据库中。
Ravinder Reddy 的问题是错误的,如果你这样做,你会错过很多空间。
如果您设置 VARBINARY(16) 并遇到“数据对于列来说太长”错误,这表明插入的数据不是格式正确的二进制 UUID。如果 VARBINARY(16) 不起作用,请在插入数据库之前仔细检查 UUID 是否已正确转换为 16 字节二进制格式。
您只需将其添加到 id 中:
@GeneratedValue(strategy = GenerationType.UUID)