java - 在 Spring MVC + Hibernate 中自动生成唯一的随机字符串

标签 java spring hibernate jpa uuid

背景

我正在使用 Spring MVC(Framework v4.0.6.RELEASE,JPA v1.6.2.RELEASE)和 Hibernate(Core v4.3.6.FINAL,JPA API v2.1)编写一个项目。在我的项目中,有一些名为“项目”的实体。这些项目中的每一个都有其唯一的、自动生成的 ID 作为主键。此 ID 由以下代码生成:

@Id
@Column(name = "project_id")
@GeneratedValue(strategy = GenerationType.AUTO)
private Long projectId;

此代码按预期工作并自动创建唯一 ID。

问题

这些项目中的每一个都应该有一个随机的、唯一的1“ secret ”String,就像 Facebook、Twitter 等 API 提供商分配的那样。所以,为了实现这一点,我尝试根据 Hibernate 文档使用以下代码:

@Column(name = "project_secret", nullable = false, unique = true)
@GenericGenerator(name = "uuid-gen", strategy = "uuid")
@GeneratedValue(generator = "uuid-gen")
private String projectSecret;

但是,每当我尝试创建一个新的项目实体时,都会遇到 org.springframework.dao.DataIntegrityViolationException 的根本原因:

com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: 
Column 'project_secret' cannot be null

这应该由 Hibernate 在创建时自动生成,必须是随机且唯一的1。 128 位 UUID 对我来说就足够了(32 个字符,不带破折号),我读到 Hibernate 有一个 UUID 生成器,所以这就是我的目标。

更多信息

搜索了几个小时后,我仍然无法按照我想要的方式 解决它。我找到了一种可能的解决方案,即包括:

@PrePersist
private void generateSecret(){
    this.setProjectSecret(UUID.randomUUID().toString());
}

在项目实体类中。插入此方法(并移除 @GenericGenerator@GeneratedValue 标记)时,正确生成并插入了项目 secret ;系统按预期工作;没有异常被抛出。但是,(我相信)这不能确保唯一性2 并且只会在插入重复的 secret 时导致异常。我想确保唯一性,最好使用内置的 Hibernate 生成器来解决这个问题。

(注释)

  1. 我实际上不确定是否应该强制执行唯一性。我想让每个 secret 都独一无二(理论上)可以创建一个额外的安全层,这让我可以:
  2. 我意识到 UUID 冲突的可能性非常低,因此 UUID 生成确保了概率意义上的唯一性,但我能够(或应该)确定这一点吗?

最佳答案

我以前遇到过这样的问题,一段时间后我意识到是我的数据库表导致了这个问题。这可能与您遇到的问题相同...

对于您的 project_id,确保在数据库中创建该列时使用以下内容

GENERATED ALWAYS AS IDENTITY

希望这是同一个问题,希望对您有所帮助。还建议使用 uuid2 作为您的策略。

看这里... http://docs.jboss.org/hibernate/core/3.6/reference/en-US/html/mapping.html#d0e5294

编辑

在意识到 project_secret 不是 @id 字段之后,答案是 hibernate 不支持在除 @id 字段之外的任何列上生成值。 有关更多详细信息,请参见此处:Hibernate JPA Sequence (non-Id)

关于java - 在 Spring MVC + Hibernate 中自动生成唯一的随机字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25082244/

相关文章:

java - Android:ScrollView 滚动时不会清除背景

java - 隐式类型和通配符

java - 在 Spring 中传递 Bean 依赖项的最佳方式是什么

java - "No Hibernate Session bound to thread",事务方法中断下一个事务的执行

spring - 从 Spring 2.5 迁移到 4

java - 在 Spring Boot 应用程序的 @Transactional 方法中调用 flush()

java - 涉及复杂对象的构建器模式

java - 分组依据和映射值

java - 当 Hibernate 从 4.x 升级到 5.x 以及 Spring 4.x 进行多线程时出现 ConcurrentModificationException

java - WildFly 14 - java.lang.ClassCastException : org. dom4j.DocumentFactory 无法转换为 org.dom4j.DocumentFactory