【问题标题】:Custom sequence column creation (non-Id) - Jpa Hibernate自定义序列列创建(非 Id) - Jpa Hibernate
【发布时间】:2021-08-30 04:58:04
【问题描述】:

我的 events 表中需要有一个 event_number 列,可以唯一标识每一行,但是该列不是表的@Id。每个 event_number 必须遵循某种格式,例如 EVENT100001,EVENT100002,...

我浏览了@GeneratedValue注解,发现这只能与@Id列一起使用。但后来找到this 的答案,但不确定它是否会导致任何竞争条件。

有没有更清洁的方法呢?这是我的实体

@Entity
@Table(name = "events")
public class Event {

    @Id
    @Access(AccessType.PROPERTY)
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;

    @Column(name = "event_number", nullable = false, unique = true)
    private String eventNumber;
}

【问题讨论】:

  • eventNumber的值是应该基于id生成的,还是完全独立的。
  • 完全独立,唯一的要求是遵循EVENT100001,EVENT100002,...的顺序,以EVENT100001为起始值。
  • 也许this answer 会有所帮助
  • 这在我的情况下不支持字母数字要求
  • 你应该使用MyGenerator implements ValueGenerator<String>。然后通过添加您需要的前缀来稍微修改generateValue

标签: java sql hibernate jpa entity


【解决方案1】:

你可以使用@GeneratorType注解。

您应该有一个休眠ValueGenerator 的实现。您可以在下面看到一个简单的示例。

import org.hibernate.Session;
import org.hibernate.tuple.ValueGenerator;

public class EventGenerator implements ValueGenerator<String> 
{
   public String generateValue(Session session, Object owner)
   {
      return  "EVENT" + session
            .createNativeQuery("select nextval('TST_DATA_SEQ')")
            .getSingleResult();
   }
}

然后你可以像这样使用它:

@GeneratorType(type = EventGenerator.class, when = GenerationTime.INSERT)
@Column(name = "event_number")
private String eventNumber;

【讨论】:

  • 我的应用是基于mySql的,不支持sequence,所以不得不改变获取唯一值的策略。为了获取序列值,我创建了一个表,其中 id 列设置为从 100001 开始的自动增量,并编写了一个存储过程,将一个值插入该表并返回 LAST_INSERT_ID()。在generateValue 方法中,我调用的是存储过程,而不是调用获取下一个值。现在,我面临一个新的错误。用更多细节更新问题
猜你喜欢
  • 2010-09-21
  • 2018-04-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-07-21
  • 1970-01-01
  • 2018-04-25
相关资源
最近更新 更多