【问题标题】:Can JPA be persuaded to convert between eg UUIDs and Strings?可以说服 JPA 在 UUID 和字符串之间进行转换吗?
【发布时间】:2012-01-16 19:08:56
【问题描述】:

我有一个带有 UUID 字段的 Java 对象。我希望能够以明显的方式将此对象持久保存到数据库中;但是,基本映射将使用 Java 序列化来编写它,而我希望 UUID 以其明显的字符串形式出现。有没有办法为该字段提供 UUID 字符串转换器到 JPA,该字段将在读写时使用,以便我可以自然地处理这种类型?

【问题讨论】:

标签: java jpa persistence


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    JPA 2.0 没有提供通用的方法,除了为同一字段的不同表示创建单独的 getter/setter。

    根据您的 JPA 提供者,您可以使用特定于实现的方法,例如,Hibernate 为此提供了一个uuid-char 类型:

    @Type(type = "uuid-char")
    private UUID uuid;
    

    【讨论】:

    • 我不得不承认,一位同事告诉我 JPA 2.0 没有提供通用的方式来支持它,我不太相信他。很伤心。这种需求是不是比我想象的要少?
    • 如果您觉得这很重要,您可以随时用理由描述您的需求并将其发送到 JPA 用户邮件列表:jpa-spec.java.net/lists 我相信您可以做很多事情使用 pre-* 和 post-* 生命周期事件的事情,但也许对其他人有帮助。
    • @Paul:实际上这是一个很常见的需求,也许是JPA 2.1 最期待的功能之一。
    【解决方案3】:

    您可以注释您的UUID 属性@Transient,同时提供其基于字符串的可持久表示。

    @PrePersist@PreUpdate@PostLoad 期间,您将根据UUID 设置此基于字符串的表示,或者(如果从数据库加载它)从字符串重新创建UUID .

    【讨论】:

      猜你喜欢
      • 2011-08-25
      • 1970-01-01
      • 2017-09-06
      • 2013-04-20
      • 1970-01-01
      • 2018-05-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多