我有一个Java对象,其字段是UUID。我希望能够以显而易见的方式将此对象持久化到数据库中;但是,Basic映射将使用Java序列化来编写它,而我希望UUID以其明显的字符串形式出现。有没有办法提供UUID< - >对于该字段的字符串转换器到JPA将在读取和写入时使用,所以我可以自然地处理这种类型吗?
答案 0 :(得分:5)
JPA 2.0没有提供一般方法,除了为同一字段的不同表示创建单独的getter / setter。
根据您的JPA提供程序,您可以使用特定于实现的方法,例如,Hibernate为此提供uuid-char
类型:
@Type(type = "uuid-char")
private UUID uuid;
答案 1 :(得分:4)
您可以注释UUID
属性@Transient
,同时提供其可持久的基于字符串的表示。
在@PrePersist
,@PreUpdate
或@PostLoad
期间,您将根据UUID
或(如果从数据库加载它)设置此基于字符串的表示形式从String中创建UUID
。
答案 2 :(得分:2)
Chris Lercher评论Note: Starting from JPA 2.1, a @Convert annotation can be used with an AttributeConverter<UUID, String>
。
此方法效果很好,并且与任何JPA提供程序兼容,而@Type(type = "uuid-char")
是提供程序特定的。
此外,autoApply=true
应用于每个实体的每个字段,因此不需要在每个实体中注释每个字段。请参阅文档here并查看以下示例:
转换器类
@Converter(autoApply = true)
public class UuidConverter implements AttributeConverter<UUID, String> {
@Override
public String convertToDatabaseColumn(final UUID entityValue) {
return ofNullable(entityValue)
.map(entityUuid -> entityUuid.toString())
.orElse(null);
}
@Override
public UUID convertToEntityAttribute(final String databaseValue) {
return ofNullable(databaseValue)
.map(databaseUuid -> UUID.fromString(databaseUuid))
.orElse(null);
}
}
实体
@Entity
public class Customer implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Long id;
@Column
private String name;
@Column(nullable = false, unique = true, updatable = false, columnDefinition="CHAR(36)")
private UUID customerId = randomUUID();
//.....
}
这就是它在数据库中的外观
TABLE customer
ID BIGINT(19) NO PRI (NEXT VALUE FOR SYSTEM_SEQUENCE_5D3)
NAME VARCHAR(255) YES NULL
CUSTOMER_ID VARCHAR(36) NO UNI NULL