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

时间:2014-08-01 14:15:11

标签: 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 '秘密'String,就像那些由API,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个字符w / out破折号)我读到Hibernate有一个UUID生成器,所以这就是我的目标。

更多信息

在搜索了几个小时之后,我就没有更接近解决它了我想要的方式。我找到了一个可能的解决方案,包括:

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

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

(注)

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

1 个答案:

答案 0 :(得分:4)

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

对于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)