在插入时将id视为VARCHAR,在查询Hibernate时将其视为NUMBER

时间:2016-01-18 08:04:13

标签: oracle hibernate

我需要映射旧的Oracle数据库表,然后使用将其称为LEGACYOTB。它的主键是一个数字序列,这个表为它分配了一个SQl类型VARCHAR(),其范围从'1''99999',-note:不是'00001'而是'1'没有zerofill。到目前为止,我无法将此id列更改为NUMBER(),因为它只是一个旧数据库。

我的问题是:我的Domain类应该是什么样子才能:

  1. 对Domain类执行类似的查询:

    SELECT MAX(TO_NUMBER(ID)) FROM LEGACYOTB
    
  2. 在该域类上执行插入:

    INSERT INTO LEGACYOTB(ID, ...) VALUES(...)
    

    没有遇到类似的SQL错误:

      

    ORA-01722:数字无效

  3. 我使用projection { max ('id') }但不是在#1上使用查询,而是使用它:

    SELECT MAX(ID) FROM LEGACYOTB
    

    注意没有To_NUMBER()功能 - 即使我将id映射为Long,它仍会将9视为大于1000。这也是导致insert失败的原因。

2 个答案:

答案 0 :(得分:2)

我想您的问题的目标是确定下一个id,以便在您的表LEGACYOTB中插入新行。

我认为最佳做法是让数据库为您完成这项工作:

  • 创建数据库序列以获取下一个id
  • 按数据库触发器设置id

例如

create sequence LEGACYOTB_ID 
  minvalue 1 
  maxvalue 999999999999999999999999999 
  start with 991 -- current max value + 1
  increment by 1;

create or replace trigger "LEGACYOTB_ID_BIER" 
  before insert on LEGACYOTB  
  for each row
declare
  -- local variables here
begin

  select to_char(LEGACYOTB_ID.nextval)
    into :new.id
    from dual;
end;

答案 1 :(得分:1)

只需保留String实体字段,然后从条件API 切换到HQLSQL,就可以从这样的查询中获取新ID :

select max(to_number(id)) FROM LegacyOtbEntity

无论如何,使用Criteria API进行这种简单和静态查询都是过度的。

如果您确实需要Criteria API,那么您可以创建使用@Formula注释的重复(只读)字段:

@Formula("TO_NUMBER(ID)")
private Long numberId;

而不是在投影Projections.max("numberId")中使用它。