如何在@JoinTable中使用@Version实现乐观锁?
JPA 3.1下@ManyToMany关联表实现乐观锁的方案
现状:JPA 3.1不支持直接通过@JoinTable实现中间表乐观锁
原生JPA规范中,@JoinTable对应的关联表被视为纯关联结构,JPA不会为其生成对应的实体类,而@Version注解只能作用于实体类的字段上,因此无法直接通过主实体的注解为中间表的version字段启用乐观锁。
可行的替代方案:拆分关联为带实体的双向关联
虽然你希望避免创建关联实体,但这是目前JPA规范内唯一能实现中间表乐观锁的方式——将@ManyToMany拆分为两个@OneToMany,创建专门的关联实体映射中间表,并在该实体中添加@Version字段:
1. 创建关联实体与复合主键类
关联实体映射中间表,包含联合主键和版本字段:
@Entity @Table(name = "company_relationship") @IdClass(CompanyRelationshipId.class) public class CompanyRelationship { @Id @Column(name = "company_id") private Long companyId; @Id @Column(name = "relationship_id") private Long relationshipId; @Version private Integer version; // 关联到主实体和 lookup 实体 @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "company_id", insertable = false, updatable = false) private Company company; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "relationship_id", insertable = false, updatable = false) private CompanyRelationshipLookup relationshipLookup; // getter、setter、构造方法 }
复合主键类(需实现Serializable并重写equals/hashCode):
public class CompanyRelationshipId implements Serializable { private Long companyId; private Long relationshipId; @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; CompanyRelationshipId that = (CompanyRelationshipId) o; return Objects.equals(companyId, that.companyId) && Objects.equals(relationshipId, that.relationshipId); } @Override public int hashCode() { return Objects.hash(companyId, relationshipId); } // getter、setter }
2. 修改主实体的关联注解
将原有的@ManyToMany替换为@OneToMany关联到新创建的实体:
@Audited(targetAuditMode = NOT_AUDITED) @OneToMany(mappedBy = "company", cascade = {CascadeType.PERSIST, CascadeType.MERGE}, fetch = FetchType.LAZY) private Set<CompanyRelationship> companyRelationships = new HashSet<>();
通过这种方式,你可以利用关联实体的@Version字段实现中间表的乐观锁逻辑,同时保留对关联关系的管理能力。
关于未来版本的支持
截至目前,JPA后续版本(包括规划中的JPA 4.0)没有公开计划为@JoinTable添加支持中间表额外字段(如@Version)的功能。JPA的@ManyToMany设计初衷是用于无额外属性的纯关联场景,带有额外字段的关联场景,官方始终推荐使用关联实体的方式实现。
内容的提问来源于stack exchange,提问作者Johann Kneringer
相关产品推荐
相关产品推荐

