在oracle 10g中获取不正确的序列值

时间:2014-03-25 12:03:43

标签: hibernate oracle10g

使用休眠插入记录时获取不正确的序列值,序列递增值为2。为什么会发生

CREATE TABLE  "DOCTOR" 
   (    "DOCTOR_ID" NUMBER(10,0) NOT NULL ENABLE, 
    "DOCTOR_NAME" VARCHAR2(40), 
    "PLACE" VARCHAR2(40), 
    "PHONE_NUMBER" NUMBER(10,0), 
     CONSTRAINT "DOCTOR_PK" PRIMARY KEY ("DOCTOR_ID") ENABLE
   )
/

CREATE OR REPLACE TRIGGER  "BI_DOCTOR" 
  before insert on "DOCTOR"               
  for each row  
begin   
    select "DOCTOR_SEQ1".nextval into :NEW.DOCTOR_ID from dual; 
end; 

/
 ALTER TRIGGER  "BI_DOCTOR" ENABLE

    DOCTOR_SEQ1:
    Min Value   1
    Max Value   999999999999999999999999999
    Increment By    1
    Cycle Flag  N
    Order Flag  N
    Cache Size  20
    Last Number 261

并配置hibernate

hbm:
      <id name="doctorId" type="long">
            <column name="DOCTOR_ID" precision="10" scale="0" />
            <generator class="sequence" >
                <param name="sequence">DOCTOR_SEQ1</param>
            </generator>
        </id>



  obtained values
    245 ramesh  knr 8080808080
    243 chakri  hyd 9090909090
    247 rameshreddy knr 8080808080

任何帮助将不胜感激

2 个答案:

答案 0 :(得分:0)

来自Oracle文档,

* CACHE指定数据库预先分配并保留在内存中的序列值,以便更快地访问。该整数值可以有28个或更少的数字。此参数的最小值为2.对于循环的序列,此值必须小于循环中的值的数量。您不能缓存超过给定循环序列号的值。

因此,CACHE允许的最大值必须小于以下公式确定的值:

(CEIL(MAXVALUE - MINVALUE))/ ABS(INCREMENT)

如果发生系统故障,则所有未在已提交的DML语句中使用的高速缓存序列值都将丢失。潜在的丢失值数等于CACHE参数的值。*

注意: 如果您在Oracle Real Application Clusters环境中使用序列,Oracle建议使用CACHE设置来增强性能。

NOCACHE:指定NOCACHE以指示序列的值未预先分配。如果省略CACHE和NOCACHE,则数据库默认会缓存20个序列号。

另外read this 所以试试这个序列,

CREATE SEQUENCE doctor
 START WITH     1
 INCREMENT BY   1
 NOCACHE
 NOCYCLE;

并且Order Flag需要Y才能按顺序生成序列

希望这会有所帮助!!

答案 1 :(得分:0)

序列每次递增2的原因是有两个系统都从序列中获取值。

  1. Hibernate获取序列值,例如1
  2. Hibernate然后将行插入表
  3. 您的触发器触发,获取新的序列值,例如2,并覆盖ID
  4. 要么阻止Hibernate使用序列,要么删除/禁用触发器,或者如果仍然需要触发其他非Hibernate系统,请将其修改为仅在需要时获取ID:

    CREATE OR REPLACE TRIGGER  "BI_DOCTOR" 
      before insert on "DOCTOR"               
      for each row  
      when new.doctor_id is null
    begin   
        select "DOCTOR_SEQ1".nextval into :NEW.DOCTOR_ID from dual; 
    end; 
    /