【问题标题】:ORA-00001 using oracle sequences and hibernateORA-00001 使用 oracle 序列和休眠
【发布时间】:2018-11-14 20:39:47
【问题描述】:

我是这个为我的表生成 ID 的策略:

@Entity
@Table(name="HGCTRAMITES")
@Getter
@Setter
@SequenceGenerator(name="SEQ_HGCTRAMITES", sequenceName="SEQ_HGCTRAMITES")
@ToString
public class Tramite {

我的列主键是这样的:

@Id
    @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="SEQ_HGCTRAMITES")
    private Integer codigo;

这个序列和这个表已经被其他应用程序使用了,这个表已经有数据了。

我使用的是Oracle 11g,我的方言hibernate:它是spring.jpa.database-platform=org.hibernate.dialect.Oracle10gDialect

在日志控制台中,休眠调用下一个序列的查询,但我收到错误:ORA-00001:restrição exclusiva (HELPDESK.PK_HGCTRAMITES) violada。

我的表只有 codigo 列作为主键。

为什么hibernate会搜索已经存在的id?

Hibernate: 
    select
        seq_hgctramites.nextval 
    from
        dual

【问题讨论】:

    标签: oracle hibernate jpa spring-data spring-data-jpa


    【解决方案1】:

    原因大概是这样的:

    这个序列和这个表已经被其他应用程序使用了

    您是否保证其他应用程序使用相同的序列SEQ_HGCTRAMITES 来生成主键,与 Hibernate 使用相同的方式

    默认情况下,Hibernate 期望序列增加 50,并使用从 n-50n 的数字来填充 id,其中 n 是序列生成的最后一个值。

    例如,如果您知道其他应用程序希望序列递增 1,并且只是将最后一个序列值用于连续的 id,那么您应该使用 @SequenceGenerator(..., incrementBy = 1) 来模仿这种行为。为了摆脱当前的困境,您还需要转发序列,以便两个应用程序都不会尝试使用表中已经存在的 id(您可以简单地继续从序列中选择 nextval 直到它大于任何id 已经存在)。

    如果两个应用程序都使用 JPA,那么保持 incrementBy 参数同步应该可以解决问题(不过,关于转发序列的部分仍然有效)。

    【讨论】:

      猜你喜欢
      • 2014-04-14
      • 2011-07-16
      • 1970-01-01
      • 1970-01-01
      • 2012-07-09
      • 1970-01-01
      • 1970-01-01
      • 2013-04-03
      • 1970-01-01
      相关资源
      最近更新 更多