Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xslt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
JPA中的唯一Id(多租户)_Jpa_Multi Tenant - Fatal编程技术网

JPA中的唯一Id(多租户)

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

我目前正在开发一个使用JPA(Hibernate)的多租户应用程序。对于某些表,我需要一个对每个租户唯一的序列号。因此,我无法对这些字段使用
@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一起)来模拟嵌套事务: