针对 MySQL 在 Hibernate 实体中建模 UUID
Modeling UUID in Hibernate entity against MySQL
我有一个与 this one 非常 相似的问题,但是我的问题比那个问题更基础,所以我 不觉得 就像一个骗局......(我们会看到 SO 的想法)。 和如果它是另一个问题的骗局,请向我指出(也许在评论中)接受的答案如何完全 answers/addresses 我的问题(我不这么认为!)。
我有一个 Java/JPA/Hibernate @Entity
class 需要一个 UUID
字段:
@Canonical
@MappedSuperclass
public abstract class BaseEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private UUID refId;
// Getters/setters/ctors/etc.
}
@Entity(name = "accounts")
@AttributeOverrides({
@AttributeOverride(name = "id", column=@Column(name="account_id")),
@AttributeOverride(name = "refId", column=@Column(name="account_ref_id"))
})
public class Account extends BaseEntity {
// blah whatever
}
也就是说,我需要在应用程序层使用 UUID。然而,这里的数据库是 MySQL,在 MySQL 中表示 UUID 的压倒性建议似乎是将它们表示为 VARCHAR(36)
,这就是我所拥有的。
在运行时出现以下异常:
Caused by: org.hibernate.HibernateException: Wrong column type in my_db.accounts for column account_ref_id. Found: varchar, expected: binary(255)
at org.hibernate.mapping.Table.validateColumns(Table.java:373)
at org.hibernate.cfg.Configuration.validateSchema(Configuration.java:1338)
<rest of stack trace omitted for brevity>
所以 很明显,数据库显示 VARCHAR(36)
,但 Hibernate 似乎默认期望 binary(255)
。
老实说,我不关心 UUID 在数据库中的存储方式。它可能是 VARCHAR
,它可能是 TEXT
,它可能是 BLOB
...它可能是我所关心的烤箱!但这里的本质要求是数据模型(实体class)使用UUID
s.
这里有什么解决方法?如果我必须更改数据库中的列类型,我应该将类型更改为什么?如果我必须 change/modify 实体中的 UUID
字段,我还需要用什么来注释它?
像这样尝试:
public class BaseEntity{
@Column(nullable = false)
private String uuid;
public BaseEntity(){
setUuid(UUID.randomUUID().toString());
}
public String getUuid() {
return uuid;
}
public void setUuid(String uuid) {
this.uuid = uuid;
}
@PrePersist
public void prePersist(){
if(null == getUuid())
setUuid(UUID.randomUUID().toString());
}
....
列定义:
uuid varchar(255) DEFAULT NULL
生成UUID
时使用toString
方法:
entity.setUuid(UUID.randomUUID().toString())
对我来说,修复需要更改数据库架构和实体 (Java) 代码。
首先,我将 CREATE TABLE
语句更改为使用 BINARY(255)
而不是 VARCHAR(36)
:
CREATE TABLE IF NOT EXISTS accounts (
# lots of fields...
account_ref_id BINARY(255) NOT NULL,
# ...lots of other fields
);
接下来我在实体中的字段声明中添加了 @Type(type="uuid-binary")
:
@Canonical
@MappedSuperclass
public abstract class BaseEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Type(type="uuid-binary")
private UUID refId;
// Getters/setters/ctors/etc.
}
@Entity(name = "accounts")
@AttributeOverrides({
@AttributeOverride(name = "id", column=@Column(name="account_id")),
@AttributeOverride(name = "refId", column=@Column(name="account_ref_id"))
})
public class Account extends BaseEntity {
// blah whatever
}
这对我来说效果很好。
我有一个与 this one 非常 相似的问题,但是我的问题比那个问题更基础,所以我 不觉得 就像一个骗局......(我们会看到 SO 的想法)。 和如果它是另一个问题的骗局,请向我指出(也许在评论中)接受的答案如何完全 answers/addresses 我的问题(我不这么认为!)。
我有一个 Java/JPA/Hibernate @Entity
class 需要一个 UUID
字段:
@Canonical
@MappedSuperclass
public abstract class BaseEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private UUID refId;
// Getters/setters/ctors/etc.
}
@Entity(name = "accounts")
@AttributeOverrides({
@AttributeOverride(name = "id", column=@Column(name="account_id")),
@AttributeOverride(name = "refId", column=@Column(name="account_ref_id"))
})
public class Account extends BaseEntity {
// blah whatever
}
也就是说,我需要在应用程序层使用 UUID。然而,这里的数据库是 MySQL,在 MySQL 中表示 UUID 的压倒性建议似乎是将它们表示为 VARCHAR(36)
,这就是我所拥有的。
在运行时出现以下异常:
Caused by: org.hibernate.HibernateException: Wrong column type in my_db.accounts for column account_ref_id. Found: varchar, expected: binary(255)
at org.hibernate.mapping.Table.validateColumns(Table.java:373)
at org.hibernate.cfg.Configuration.validateSchema(Configuration.java:1338)
<rest of stack trace omitted for brevity>
所以 很明显,数据库显示 VARCHAR(36)
,但 Hibernate 似乎默认期望 binary(255)
。
老实说,我不关心 UUID 在数据库中的存储方式。它可能是 VARCHAR
,它可能是 TEXT
,它可能是 BLOB
...它可能是我所关心的烤箱!但这里的本质要求是数据模型(实体class)使用UUID
s.
这里有什么解决方法?如果我必须更改数据库中的列类型,我应该将类型更改为什么?如果我必须 change/modify 实体中的 UUID
字段,我还需要用什么来注释它?
像这样尝试:
public class BaseEntity{
@Column(nullable = false)
private String uuid;
public BaseEntity(){
setUuid(UUID.randomUUID().toString());
}
public String getUuid() {
return uuid;
}
public void setUuid(String uuid) {
this.uuid = uuid;
}
@PrePersist
public void prePersist(){
if(null == getUuid())
setUuid(UUID.randomUUID().toString());
}
....
列定义:
uuid varchar(255) DEFAULT NULL
生成UUID
时使用toString
方法:
entity.setUuid(UUID.randomUUID().toString())
对我来说,修复需要更改数据库架构和实体 (Java) 代码。
首先,我将 CREATE TABLE
语句更改为使用 BINARY(255)
而不是 VARCHAR(36)
:
CREATE TABLE IF NOT EXISTS accounts (
# lots of fields...
account_ref_id BINARY(255) NOT NULL,
# ...lots of other fields
);
接下来我在实体中的字段声明中添加了 @Type(type="uuid-binary")
:
@Canonical
@MappedSuperclass
public abstract class BaseEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Type(type="uuid-binary")
private UUID refId;
// Getters/setters/ctors/etc.
}
@Entity(name = "accounts")
@AttributeOverrides({
@AttributeOverride(name = "id", column=@Column(name="account_id")),
@AttributeOverride(name = "refId", column=@Column(name="account_ref_id"))
})
public class Account extends BaseEntity {
// blah whatever
}
这对我来说效果很好。