背景
我正在使用 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 生成器来解决这个问题。
(注释)
- 我实际上不确定是否应该强制执行唯一性。我想让每个 secret 都独一无二(理论上)可以创建一个额外的安全层,这让我可以:
- 我意识到 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/