面向客户的hibernate实体ID

时间:2014-06-11 16:29:04

标签: java oracle hibernate

我的应用程序要求我为实体生成“面向客户的ID”。 ID必须唯一标识实体以供客户参考,但不能是DB中使用的主键。它也不能是一个连续的值,所以它更难预测。

我已经着手为我的实体创建ID字段的排列,我有那部分工作。我现在遇到的问题是我不确定在Hibernate中处理这个问题的最佳方法,因为在生成ID之前我无法生成排列。

我使用Oracle作为数据库,并使用序列生成ID。有没有办法在从序列中检索ID时捕获ID,创建我的排列,并在将实体插入数据库之前在实体上设置值?或者,我是否坚持保存实体,设置排列值,然后更新实体?

另外,我愿意就如何满足这些要求提出更好的建议吗?

1 个答案:

答案 0 :(得分:0)

您可以在11g中使用虚拟列。首先,创建一个基本函数,根据您认为应该确定标识符的字段生成md5哈希:

create or replace function get_naddr_hash(i_string in varchar2, i_uppercase in number default 0)
return varchar2 deterministic
as
    l_string varchar2(32767);
begin
    l_string := substr(i_string, 1, 32767);
    if (i_uppercase > 0) then
        l_string := upper(l_string);
    end if;

  return rawtohex(
    DBMS_CRYPTO.Hash (
        UTL_I18N.STRING_TO_RAW (l_string, 'AL32UTF8'),
        2)
    );
end;

请注意,此函数要求已在db上设置dbms_crypto。

然后使用此函数创建(或通过ctas重新创建)具有虚拟列的表:

create table tst_tab
(
naddr_hash as (get_naddr_hash(trim(username)||trim(address1)||trim(city)||trim(state), 1)),
username varchar2(100) not null,
address1 varchar2(100) not null,
address2 varchar2(100),
city varchar2(100) not null,
state varchar2(2) not null,
zip varchar2(9),
phone varchar2(20)
);

在这里,我认为用户名,地址1,城市,州将是确定字段。在这个设置之后,你应该很高兴。

insert into tst_tab
(
username, address1, address2, city, state, zip, phone
) values
(
'Joe Smith', '123 Main St', 'Ste 100', 'Denver', 'CO', '12345', '5551212'
);

insert into tst_tab
(
username, address1, address2, city, state
) values
(
'JOE SMITH', '123 Main St', 'Ste 101', 'Denver', 'CO'
);

这两个将具有相同的naddr_hash。以下将使用不同的哈希:

insert into tst_tab
(
username, address1, address2, city, state
) values
(
'JANE SMITH', '123 Main St', 'Ste 101', 'Denver', 'CO'
);

查看数据:

NADDR_HASH  USERNAME
2ADCBCAC3A26ED5BD189351B84BFA412    Joe Smith
2ADCBCAC3A26ED5BD189351B84BFA412    JOE SMITH
C56D5007C89284892FDF03A96C5E15E0    JANE SMITH