gpt4 book ai didi

java - 没有良好 PK 的 Oracle 遗留表 : How to Hibernate?

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:12:57 25 4
gpt4 key购买 nike

我在 Oracle 数据库中有遗留表,我想从具有 Hibernate 的 Java 应用程序访问这些表。问题是:表没有好的主键。例如,一个表看起来像这样:

create table employee (
first_name varchar(64) not null,
last_name varchar(64) not null,
hired_at date,
department varchar(64)
);
create unique index emp_uidx on employee (firstname, lastname, hired_at);

最初的设计者决定使用 hired_at 列作为状态字段,认为数据库永远不需要区分公司外部的 John Smiths,但可以将同名员工由他们的 hired_at 日期确定。显然,这会创建一个部分可为空且可修改的主键。由于数据库不允许将其作为主键,他改为使用唯一索引。

现在,如果我尝试为此编写一个 Hibernate 映射,我可能会想到这样的事情:

<hibernate-mapping>
<class name="com.snakeoil.personnel" table="employee">
<composite-id class="com.snakeoil.personnel.EmpId" name="id">
<key-property name="firstName" column="first_name" type="string"/>
<key-property name="lastName" column="last_name" type="string"/>
</composite-id>
<property name="hiredAt" column="hired_at" type="date"/>
<property name="department" type="string">
</class>
</hibernate-mapping>

这适用于读取数据,但是当我创建仅在雇用日期不同的新条目时,我遇到了 org.hibernate.NonUniqueObjectExceptions。或者,我可能会考虑 Oracle 的 ROWID 特性:

<id column="ROWID" name="id" type="string">
<generator class="native"/>
</id>

这也适用于读取数据。但显然,您不能持久化新对象,因为 Hibernate 现在会抛出 org.hibernate.exception.SQLGrammarException:在尝试存储实体时无法获取下一个序列值。

解决这个问题的明显方法是通过代理键。然而,这将需要更改数据库模式,这让我们回到那个“遗留”的东西。

我忽略了什么?有没有办法让 Hibernate 与 Oracle 的 ROWID 合作,也许使用不同的生成器?或者有没有办法让第一个想法奏效,也许使用聪明的 DAO 大量驱逐和重新加载实体,并隐藏应用程序的复杂性?或者我应该寻找 Hibernate 的替代品,也许是 Ibatis?

最佳答案

您不想使用 ROWID 作为主键,因为它不能保证在行的生命周期内保持稳定。

添加合成 key 是最好的选择。使用触发器用序列值填充列。

您在遗留方面有点含糊,因此很难确定其含义是什么。添加列会破坏任何未明确列出目标列的插入语句。它还可能会破坏任何 SELECT * 查询(除非他们选择使用 %ROWTYPE 关键字声明的变量。但是您不必更改任何其他应用程序,因此它使用新的主键而不是现有的列 - 除非你真的想要。

关于java - 没有良好 PK 的 Oracle 遗留表 : How to Hibernate?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1519078/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com