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 这是不可能的。想象以下场景:您有实体Dog
和Cat
,它们继承自Animal
。现在您尝试通过 ID 获取 Animal
的实例。结果应该是什么? (显然可以提出明确的行为——比如引发错误——但问题是它是否有用或值得实施。)以上是关于Java 持久性继承中的序列号的主要内容,如果未能解决你的问题,请参考以下文章