在Oracle上使用Hibernate序列,@GeneratedValue(strategy = GenerationType.AUTO)

25

我正在使用 @GeneratedValue(strategy = GenerationType.AUTO) 生成实体的 ID。

我不知道它是如何工作的,但在我的子表中,它会生成遵循父序列的 ID 值。

//parent table
@Entity
@Table (name = "parent")
public class Parent {

    @Id
    @GeneratedValue (strategy = GenerationType.AUTO)
    @Column (name = "id")
    private long id;


    @OneToMany (cascade = {CascadeType.ALL}, fetch = FetchType.LAZY)
    @JoinColumn (name = "parentId")
    @ForeignKey (name = "FKparent")
    private List<child> child;

}

//child table
@Entity
@Table (name = "child")
public class Child {

    @Id
    @GeneratedValue (strategy = GenerationType.AUTO)
    @Column (name = "id")
    private long id;
}
父级插入的ID值更新了序列,子级插入的ID值也更新了序列。 在下一次父级插入时,序列使用子级插入更新的值...... 这些注释并没有创建两个序列,只有一个。这是正确/预期的吗? 我只使用entityManager.persist(parent);通过我的DAO服务插入了实体。
3个回答

56
这是期望的行为。使用 @GeneratedValue(strategy = GenerationType.AUTO) 时,JPA提供者会选择适合特定数据库的策略。在Oracle的情况下,这将是SEQUENCE, 而且由于您没有指定任何内容,Hibernate将使用一个名为 hibernate_sequence 的单个全局序列。
这是否正确?嗯,我不知道,这取决于您的需求。以防万一,Oracle序列的默认最大值为1E + 27,即1,000,000,000,000,000,000,000,000,000。这对于许多情况已足够。
现在,当数据库使用序列时,仍然可以使用GenerationType.AUTO 并控制序列的名称:
@Id
@GeneratedValue(strategy=GenerationType.AUTO, generator="my_entity_seq_gen")
@SequenceGenerator(name="my_entity_seq_gen", sequenceName="MY_ENTITY_SEQ")
private Long id;

6
如果你想使用GenerationType.AUTO允许其他数据库(如MySQL)使用Identity Insert,那么在Pascal中这样做将行不通,对吗?因为你手动指定一个生成器。 - lujop

1

是的,这是正确的并且是预期的。

你可以为每个表创建单独的序列,但在我看来,这只是额外的代码,没有实际的好处。


不要让最终用户看到那些键并被它的“跳跃”所误导。而且不要告诉我需要隐藏键,这并不总是可能的... - Monoman
1
没有办法在时间和单调性上保持ID的恒定性,而且不会在序列中留下空洞,这样做会破坏可扩展性。我也没有看到有用的“跳跃”定义以及用户为什么需要非跳跃式的ID。 - Jens Schauder

1
@Entity
@Table(name = "table_seq")
@SequenceGenerator(name= "NAME_SEQUENCE", sequenceName = "SEQ_ID", initialValue=1, allocationSize = 1)
public class SeqEntity implements Serializable {
  private static final long serialVersionUID = 1L;

 @Id
 @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="NAME_SEQUENCE")
 private Long id;

}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接