我遇到了一个问题,试图选择更新行使用Spring Data 与Hibernate作为JPA实现和Postgresql。
假设我们有实体A,B,C.
public class A{
@Id
private Long id;
@OneToMany(fetch = FetchType.EAGER)
private Set<B> bSet;
@OneToMany(fetch = FetchType.EAGER)
private Set<C> cSet;
}
字符串
假设我们想要选择A和所有相关的B和C实体进行更新,即锁定与A表相关的行。
@Query(SELECT a FROM A a
LEFT JOIN FETCH a.bSet
LEFT JOIN FETCH a.cSet
WHERE a.id=?)
@Lock(LockModeType.PESSIMISTIC_WRITE)
public A selectAndLockA(Long Aid);
型
查询将类似于
SELECT a.column1, ... from tableA a LEFT JOIN tableB b ... FOR UPDATE of a,c
型
对于a,c的更新
查询将尝试锁定两个表,这会导致异常,如:org.postgresql.util.PSQLException:ERROR:FOR UPDATE不能应用于外部连接的可空端
我尝试归档的是锁定第一个表“FOR UPDATE OF A”
有没有可能以某种方式配置或告诉Hibernate只锁定第一个表。
4条答案
按热度按时间hgqdbh6s1#
PostreSQL不支持这一点。如果你做了一个外部SELECT,没有什么可以阻止某人插入一行到LEFT JOINED表中,从而修改你正在查看的结果集(例如,在重复读取时,列将不再是NULL)。
有关详细说明,请参见here
zwghvu4y2#
这是一个很长一段时间以来的问题,但我有一个类似的问题,希望我的答案将帮助别人。
假设我们有这个JPA实体:
个字符
我们希望选择CardTransactionsEntity with fetched ReceivtsEntity用于仅悲观更新CardTransactionsEntity。这可以使用Hibernate和Spring Data JPA存储库来完成,
型
此存储库方法将执行查询,如
型
kyks70gy3#
使用FetchType. LAZY连接表可以绕过此错误。此提取类型是默认类型,不需要为@OneToMany连接指定。
字符串
62lalag44#
老问题,但我的用例描述可能对某人有帮助。
我在同一个查询中有很多表的连接+ @ passiotyGraph来获取一些东西。但只需要在一个主表中PESIMISTIC_passiotyGraph。
早期提出的从锁中排除表的解决方案很麻烦(大量的排除),在@ MyrtyGraph的情况下还有未知的别名。
因此,我们可以通过只提供@QueryHints来指定锁的确切表(而不是整个层次结构):
字符串
但即使在这种情况下,Hibernate中也存在一个错误。来自HQL的别名会被来自@ MyrtyGraph的隐式别名干扰。
解决方案:摆脱@ MyrtyGraph,只通过HQL获取所有内容。
型