JPA中的唯一Id(多租户)
我目前正在开发一个使用JPA(Hibernate)的多租户应用程序。对于某些表,我需要一个对每个租户唯一的序列号。因此,我无法对这些字段使用JPA中的唯一Id(多租户),jpa,multi-tenant,Jpa,Multi Tenant,我目前正在开发一个使用JPA(Hibernate)的多租户应用程序。对于某些表,我需要一个对每个租户唯一的序列号。因此,我无法对这些字段使用@GeneratedValue。我决定使用一个名为Sequence的额外实体,该实体带有一个用@Version注释的长字段。请求新id时,我会执行以下操作: Sequence seq = em.find(Sequence.class, pk, LockModeType.PESSIMISTIC_FORCE_INCREMENT); long nextId = s
@GeneratedValue
。我决定使用一个名为Sequence的额外实体,该实体带有一个用@Version
注释的长
字段。请求新id时,我会执行以下操作:
Sequence seq = em.find(Sequence.class, pk, LockModeType.PESSIMISTIC_FORCE_INCREMENT);
long nextId = seq.id;
只要我不运行应用程序两次,这就行了。然后我得到以下异常:
线程“main”javax.persistence.OptimisticLockException中的异常:
org.hibernate.StaleObjectStateException:行已由更新或删除
另一个事务(或未保存的值映射不正确)
序列没有被“正确”锁定,我一提交就得到一个异常。因为JPA不支持嵌套事务,所以我不能更早地检测到它。我尝试了其他一些方法,但也失败了
那么,是否有其他(可移植)解决方案允许我在多租户上下文中生成唯一密钥?您没有正确使用@Version注释。此注释将数字字段设计为版本字段,并由JPA在执行事务锁定时在内部使用。你不应该真的写,甚至(除了某些情况)不应该读。你最初的想法是对的:制作一个音序器,但你不需要使用@Version。只要有一个包含原子整数的类,每次需要一个新的唯一值时,该类都会递增,然后保存到表中的db。我已经尝试了你的建议。这个解决方案的问题是,在提交整个事务(这就是我所说的嵌套事务)之前,我不会检测事务重叠。好吧,你不会喜欢我的建议,但是如果你真的想要嵌套事务,你可能想放弃Hibernate/JPA。您可以直接转到JDBC,或使用Spring保存点(与JDBC一起)来模拟嵌套事务: