Hibernate @ManyToMany关联表含独立自增非空主键要如何配置?
Spring Data JPA多对多关联表带独立自增主键的解决方案
原生JPA的@ManyToMany注解没有提供直接指定关联表自增id生成的标准配置,因为JPA规范中默认多对多关联表使用两个外键组成复合主键,不会处理额外的独立主键字段。不过你可以通过Hibernate的扩展注解实现需求,不需要拆分@OneToMany关系,也不用修改现有表结构,有以下两种可行方案:
方案1:依赖数据库自增能力+自定义插入语句
该方案改动量最小,不需要调整业务逻辑:
- 第一步:先确认关联表
portal_user_user_type的id字段在数据库层面已经配置自增规则,以PostgreSQL为例,修改表结构为id添加自增属性:
ALTER TABLE public.portal_user_user_type ALTER COLUMN id ADD GENERATED ALWAYS AS IDENTITY;
如果是MySQL则直接将id字段定义改为id bigint NOT NULL AUTO_INCREMENT PRIMARY KEY即可。
- 第二步:在User实体的多对多关联字段上添加Hibernate的
@SQLInsert注解,指定插入关联表时只填充两个外键字段,id由数据库自动生成:
@ManyToMany @JoinTable( name = "portal_user_user_type", joinColumns = @JoinColumn(name = "portal_user_id_fk"), inverseJoinColumns = @JoinColumn(name = "user_type_id_fk") ) @SQLInsert(sql = "INSERT INTO portal_user_user_type (portal_user_id_fk, user_type_id_fk) VALUES (?, ?)") private Set<UserType> userTypes;
方案2:使用Hibernate专属@CollectionId注解维护关联表主键
如果不想在数据库层面设置id自增,可以由Hibernate来管理关联表的主键生成,配置如下:
@ManyToMany @JoinTable( name = "portal_user_user_type", joinColumns = @JoinColumn(name = "portal_user_id_fk"), inverseJoinColumns = @JoinColumn(name = "user_type_id_fk") ) @CollectionId( columns = @Column(name = "id"), generator = "user_type_rel_id_gen", type = @Type(type = "java.lang.Long") ) @GenericGenerator( name = "user_type_rel_id_gen", strategy = "org.hibernate.id.enhanced.SequenceStyleGenerator", parameters = { @Parameter(name = "sequence_name", value = "portal_user_user_type_id_seq"), @Parameter(name = "increment_size", value = "1") } ) private Set<UserType> userTypes;
该方案不需要修改数据库表的自增配置,由Hibernate调用序列生成主键值,同样不需要拆分多对多关系。
内容的提问来源于stack exchange,提问作者AndreaNobili
相关产品推荐
相关产品推荐

