小编wal*_*orn的帖子

Oracle遗留表没有很好的PK:如何进行Hibernate?

我在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);
Run Code Online (Sandbox Code Playgroud)

最初的设计师决定使用该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>
Run Code Online (Sandbox Code Playgroud)

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

<id column="ROWID" name="id" type="string">
   <generator class="native"/>
</id>
Run Code Online (Sandbox Code Playgroud)

这对于读取数据也很好.但显然,你不能坚持新的对象,因为Hibernate现在抛出一个org.hibernate.exception.SQLGrammarException:在尝试存储实体时无法获得下一个序列值.

显而易见的方法是通过代理键.然而,这将需要更改数据库模式,这将我们带回到"遗留"的东西.

我在俯瞰什么?有没有办法让Hibernate与Oracle的ROWID合作,可能使用不同的生成器?或者有没有办法让第一个想法发挥作用,也许有聪明的DAO可以驱逐和重新加载实体,并隐藏应用程序的复杂性?或者我应该寻找Hibernate的替代方案,Ibatis可能吗?

java oracle hibernate

7
推荐指数
2
解决办法
5576
查看次数

JPA:关于OneToMany关系中阻抗不匹配的问题

我有一个关于JPA-2.0(提供者是Hibernate)关系及其在Java中的相应管理的问题.假设我有一个部门和一个员工实体:

@Entity
public class Department {
  ...
  @OneToMany(mappedBy = "department")
  private Set<Employee> employees = new HashSet<Employee>();
  ...
}

@Entity
public class Employee {
  ...
  @ManyToOne(targetEntity = Department.class)
  @JoinColumn
  private Department department;
  ...
}
Run Code Online (Sandbox Code Playgroud)

现在我知道我必须自己管理Java关系,如下面的单元测试:

@Transactional
@Test
public void testBoth() {
  Department d = new Department();
  Employee e = new Employee();
  e.setDepartment(d);
  d.getEmployees().add(e);
  em.persist(d);
  em.persist(e);
  assertNotNull(em.find(Employee.class, e.getId()).getDepartment());
  assertNotNull(em.find(Department.class, d.getId()).getEmployees());
}
Run Code Online (Sandbox Code Playgroud)

如果我遗漏e.setDepartment(d)d.getEmployees().add(e)断言将失败.到现在为止还挺好.如果我之间提交数据库事务怎么办?

@Test
public void testBoth() {
  EntityManager em = emf.createEntityManager();
  em.getTransaction().begin();
  Department d = new Department();
  Employee …
Run Code Online (Sandbox Code Playgroud)

java orm jpa jpa-2.0

4
推荐指数
2
解决办法
1121
查看次数

标签 统计

java ×2

hibernate ×1

jpa ×1

jpa-2.0 ×1

oracle ×1

orm ×1