Java 持久性继承中的序列号

Posted

技术标签:

【中文标题】Java 持久性继承中的序列号【英文标题】:Sequence Numbers in Java Persistence Inheritance 【发布时间】:2012-11-14 22:48:50 【问题描述】:

使用 JSF 和 JPA 开发应用程序。

@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)

Bill 是父类,是 OpdBill、PharmacyBill 等的子类。

多个用户可能会尝试同时持久化。

为 Bill 类生成序列号很容易,但这在功能中不是必需的。 我们如何为子类单独自动生成序列号? (不需要ID,只要序列号)

【问题讨论】:

如果OpdBill也是一个Bill,那么一个OpdBill-instance会有两个ID?这就是你想要的吗? OPD 是一个独立的部门。他们想要单独的序列号。实验室是一个独立的部门,他们想要有自己的号码。尽管管理层在大多数报告中将所有账单一起分析,但不需要为账单设置单独的序列号。我使用单表继承。 @BuddhikaAriyaratne 你的部门都傻了。序列号应该或多或少是任意的,您可以保证的唯一约束是它们将严格单调递增。例如,不可能保证 ID 序列中没有任何间隙。中止的事务将导致这些,防止它们的唯一方法是使数据库操作同步并降低性能。 【参考方案1】:

据我所知,JPA 无法为非 ID 列创建此类序列,但您可以像这样做一些肮脏的解决方法:

生成第二个实体,如

@Entity
public class OpdSequence 
  @Id
  @GeneratedValue
  private Long id;

并为您的 OpdBill 创建一个 1-1

@Entity 
public class OpdBill extends Bill 
  @OneToOne
  private OpdSequence opdId;

【讨论】:

当然这不再是真正的 JPA 继承了。 (它实现了同样的效果,是一种有效的解决方法,它可以说是整体上更可取的模式,但它不是功能本身。)【参考方案2】:

如果 OpdBill 是一个账单,那么两者必须共享相同的 ID 字段,并且 Hibernate 必须能够通过它们的 ID 区分两个账单(无论它们的类别是什么)。因此,所有子类必须与基类共享相同的 ID 生成,并且 Bill 及其子类的所有实例的 ID 必须是唯一的。

【讨论】:

这是否意味着通过单继承,我们无法获得子类的唯一编号(本质上不是 ID)? @BuddhikaAriyaratne 这是不可能的。想象以下场景:您有实体DogCat,它们继承自Animal。现在您尝试通过 ID 获取 Animal 的实例。结果应该是什么? (显然可以提出明确的行为——比如引发错误——但问题是它是否有用或值得实施。)

以上是关于Java 持久性继承中的序列号的主要内容,如果未能解决你的问题,请参考以下文章

java 序列化 - 持久化类定义

Qt持久性对象进行序列化(同时比较了MFC与Java的方法)

Qt持久性对象进行序列化

Java安全之反序列化漏洞分析

Hadoop序列化与Java序列化

arraylist如何在序列化后持久保存数据