【问题标题】:Different column types for different databases with JPA使用 JPA 的不同数据库的不同列类型
【发布时间】:2014-01-30 15:06:55
【问题描述】:

是否可以根据使用的数据库使用 JPA 定义不同的列类型?

我需要将 id 存储为 uuid,并且它必须是可移动的。那就是问题所在。 PostgreSQL 有 'uuid',MSSQL 'uniqueidentifier' 而 Oracle 什么都没有,我认为必须使用 'RAW'。

有什么想法可以帮助我吗?

编辑: 目前,id 是使用 java.util.UUID 生成的,并作为 varchar 存储在数据库中。但是由于该数据类型的性能问题,我想将 id 存储为 uuid 类型。 对于 Oracle,必须使用 RAW 类型,因为不存在 uuid 类型。如何告诉 JPA 在 PostgreSQ/MSSQL 中使用 uuid 类型,在 Oracle 中使用 RAW 类型?

【问题讨论】:

  • varchar 如何产生性能问题?这是我第一次听说。我不认为性能问题来自 varchar,但可能来自缺少索引和/或键。
  • 我不认为 varchars 是性能问题的原因。但是使用 uuid 类型可以提高 10% 到 30% 的性能。现在我的任务是找出如何在所有支持的数据库中使用 uuid 类型
  • 执行类似的操作需要将元数据与类分离,因此根据数据存储区的不同,可以将 1 个类与不同的元数据一起使用(而您不能使用注释来做到这一点)。 JPA 不够灵活,无法提供这种功能(即使使用其 XML 元数据);您可能会获得一些特定于供应商的选项,但随后会失去供应商的可移植性。唯一允许所有这些的持久性标准是 JDO。

标签: java database oracle jpa


【解决方案1】:

您可以使用 java.util.UUID 来生成您的 uuid 并将其存储到字符可变(60)列类型中。 现在,既然您想成为主键,那么自动生成它应该是好的。所以你可以在 PrePersist 的类上添加一个实体监听器:

@EntityListeners({ AbstractEntity.AbstractEntityListener.class})
public class Entity {

    public static class AbstractEntityListener {
        @PrePersist
        public void onPrePersist(Entity entity) {
            entity.uid();
        }
    }

    private String uid() {
        if (uid == null)
          uid = UUID.randomUUID().toString();
        return uid;
    }
}

请注意,我没有对此进行测试。所以它可能无法 100% 工作。

【讨论】:

  • 感谢您的快速答复。我解释得不够。这就是当前状态,id 是用 java.util.UUID 生成的,并作为 varchar 存储在数据库中。现在我想将它存储为 uuid 类型,但 Oracle 没有。这是我的问题,我该如何解决?我编辑了我的问题以使其更准确。
  • 如果你使用 Hibernate 作为 jpa 提供者,你可以使用这样的东西:@Id @GeneratedValue(generator="system-uuid") @GenericGenerator(name="system-uuid", strategy = “uuid”)
  • 我可以这样做,但是 JPA 在不同的数据库中创建了疯狂的列类型。我想指定为每个数据库创建的类型。
【解决方案2】:

我会使用SequenceGenerator。查看this answer 了解更多详情。你将不得不制作一个序列。每个实体的生成器,以确保您不会遇到并发问题。 还要确保您设置了一个好的/不存在的初始值。

【讨论】:

  • 谢谢,但这对我没有帮助。我需要 UUID
猜你喜欢
  • 2020-12-08
  • 2012-03-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-29
相关资源
最近更新 更多