Spring Boot JPA使用@ManyToOne时如何仅映射外键id而非整个关联对象
@ManyToOne仅映射外键ID的实现方案
共有三种常用实现方式,可根据业务场景选择:
方案1:仅映射外键字段,移除@ManyToOne关联
适用场景:不需要操作关联对象、无需关联查询,仅使用外键ID的业务场景,性能最优。
代码修改如下:
@Id private UUID id; private String name; private double price; private String image; private String ingredients; private String description; // 直接映射外键列,无需定义关联对象 @Column(name = "category_id") private UUID categoryId; public FoodDto mapToDto() { return new FoodDtoImpl(this.getId(), this.getName(), this.getPrice(), this.getImage(), this.getIngredients(), this.getDescription(),this.categoryId); } public void generateId(){ this.setId(UUID.randomUUID()); }
方案2:保留@ManyToOne关联,额外映射只读外键字段
适用场景:部分业务需要操作关联对象、做关联查询,同时大部分场景只需要获取外键ID,兼顾两种需求,符合JPA标准,通用性强。
注意要将外键ID字段设置为只读,避免和@ManyToOne的映射产生冲突:
@Id private UUID id; private String name; private double price; private String image; private String ingredients; private String description; // 保留关联关系,建议设置懒加载避免不必要的关联查询 @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "category_id") private CategoryImpl category; // 额外映射只读外键字段,insertable、updatable设为false避免和关联映射冲突 @Column(name = "category_id", insertable = false, updatable = false) private UUID categoryId; public FoodDto mapToDto() { // 直接读取categoryId,不会触发懒加载查询关联的Category对象 return new FoodDtoImpl(this.getId(), this.getName(), this.getPrice(), this.getImage(), this.getIngredients(), this.getDescription(),this.categoryId); } public void generateId(){ this.setId(UUID.randomUUID()); }
如果需要通过修改categoryId来更新外键,可调整映射规则:将@ManyToOne对应的@JoinColumn设置insertable = false, updatable = false,同时取消categoryId字段的这两个配置即可。
方案3:基于Hibernate特性直接从代理对象取ID
如果使用Hibernate作为ORM实现,保留原有@ManyToOne懒加载配置的前提下,直接调用category.getId()不会触发懒加载查询,可直接拿到外键ID。该方式不需要修改实体结构,但是依赖Hibernate私有特性,不具备跨ORM实现的可移植性。
内容的提问来源于stack exchange,提问作者Dark Knight
相关产品推荐
相关产品推荐

