Hibernate 5:无独立@Id的OneToOne关联配置问题
问题描述
我有一个Products类,主键配置如下:
@Id @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "products_seq") @SequenceGenerator(name = "products_seq", sequenceName = "products_seq", allocationSize = 1) @Column(name = "PRODUCT_ID") protected Integer productId;
该类包含private Attributes attributes;属性,需要与Attributes类建立@OneToOne关联。
特殊场景:Attributes类没有独立ID,对应的数据表只有ATTRIBUTE_ID和DATE两列,且ATTRIBUTE_ID并非自生成主键,而是与Products类的product_id值完全相同。
我曾尝试如下配置,但认为并非正确方案:
Products类中添加:
@OneToOne(mappedBy = "product", cascade = CascadeType.PERSIST) private Attributes attributes;
Attributes类中添加:
@Id @GeneratedValue(generator = "foreign") @GenericGenerator(name = "foreign", strategy = "foreign", parameters = @Parameter(name = "property", value = "product")) @Column(name = "ATTRIBUTE_ID") private Integer attributeId; @OneToOne(fetch = FetchType.LAZY) @JoinColumn(name = "attribute_id") private Product product;
请问是否有合适的方法处理这种特殊场景?
解决方案
你之前的思路方向是对的,这种共享主键的一对一关联场景,JPA有标准的简洁实现方式,用@MapsId注解替代Hibernate专属的foreign生成器,更符合JPA规范,具体配置如下:
1. Products类配置
保留原有主键配置,同时维护关联关系,按需设置级联操作确保数据同步:
@Entity @Table(name = "PRODUCTS") public class Products { @Id @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "products_seq") @SequenceGenerator(name = "products_seq", sequenceName = "products_seq", allocationSize = 1) @Column(name = "PRODUCT_ID") protected Integer productId; // 关联Attributes,mappedBy指定由Attributes端维护关联关系 @OneToOne(mappedBy = "product", cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REMOVE}, orphanRemoval = true) private Attributes attributes; // getter、setter方法 }
2. Attributes类配置
用@MapsId指定主键从关联的Products实体获取,无需额外主键生成策略:
@Entity @Table(name = "ATTRIBUTES") public class Attributes { @Id @Column(name = "ATTRIBUTE_ID") private Integer attributeId; @Column(name = "DATE") private LocalDate date; // 关联Products,@JoinColumn指定外键列,@MapsId表示该关联的主键将作为当前实体的主键 @OneToOne(fetch = FetchType.LAZY) @JoinColumn(name = "ATTRIBUTE_ID") @MapsId private Products product; // getter、setter方法 }
配置说明
@MapsId:告知JPA当前实体的主键值来源于关联实体(Products)的主键,保存Products时,Attributes的ATTRIBUTE_ID会自动同步为Products的productId,无需手动赋值。- 级联操作:根据业务需求配置
cascade和orphanRemoval,确保删除或更新Products时,Attributes能同步处理。 - 关联维护端:由于外键在ATTRIBUTES表,由Attributes端维护关联,因此Products端用
mappedBy指向Attributes的product属性。
使用示例
保存数据时,只需建立关联关系,JPA会自动同步主键:
Products product = new Products(); // 设置product的其他属性 Attributes attributes = new Attributes(); attributes.setDate(LocalDate.now()); attributes.setProduct(product); product.setAttributes(attributes); entityManager.persist(product);
这种方式完全适配你的场景,无需修改数据表结构,是共享主键一对一关联的标准实现方案。
内容的提问来源于stack exchange,提问作者Michu93
相关产品推荐
相关产品推荐

