Spring JPA插入实体后能否获取关联实体完整信息?
问题:仅携带关联实体ID保存后,能否获取关联实体完整信息?
在仅传入关联实体ID的情况下,使用Spring JPA的CrudRepository.save()方法保存TableA实体后,返回的实体中能否获取到关联TableB的完整信息(比如包含name字段)?
实体模型
@Entity @Table(name = "TableA") public class TableA { ... @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "tableB_id", insertable = false, updatable = false) TableB tableB; ... } @Entity @Table(name = "TableB") public class TableB { ... @OneToMany(mappedBy = "tableB", fetch = FetchType.LAZY) private Collection<TableA> tableAElements; ... }
表结构
┌───────────┐ ┌───────────┐ │ TableA │ n------1 │ TableB │ ├───────────┤ ├───────────┤ │ ... │ │ tableB_id │ │ tableB_id │ │ name │ └───────────┘ └───────────┘
待插入数据
{ // table A信息 ... tableB: { id: 1 } }
回答
默认情况无法直接获取完整TableB信息
按你当前的配置,save()返回的TableA实体里,tableB只是个代理对象,只会保留你传入的id值,不会自动加载name等其他字段,原因有两点:@ManyToOne配置了fetch = FetchType.LAZY:懒加载模式下,关联实体不会随主实体一起加载,只有调用tableB的getter方法时才会触发额外SQL查询。@JoinColumn设置了insertable = false, updatable = false:这个配置让JPA不会通过TableA维护tableB_id字段的增改,你传入的id仅用于关联,save操作本身不会触发TableB的查询。
获取完整TableB信息的三种方式
- 手动触发懒加载(需在事务内):
在save返回实体后,调用tableB的getter方法(确保当前处于事务中,否则会抛出LazyInitializationException):@Transactional public TableA saveAndGetFullTableA(TableA tableA) { TableA saved = tableARepository.save(tableA); // 触发懒加载,加载完整TableB数据 saved.getTableB().getName(); return saved; } - 修改为饿汉加载:
把@ManyToOne的fetch改为FetchType.EAGER,这样保存或查询TableA时会自动关联加载完整TableB,但注意会增加SQL开销,数据量大时需谨慎:@ManyToOne(fetch = FetchType.EAGER) @JoinColumn(name = "tableB_id", insertable = false, updatable = false) TableB tableB; - 自定义查询主动关联加载:
在Repository中定义带JOIN FETCH的查询方法,保存后调用该方法获取完整数据:public interface TableARepository extends CrudRepository<TableA, Long> { @Query("SELECT a FROM TableA a JOIN FETCH a.tableB WHERE a.id = :id") TableA findByIdWithTableB(Long id); }
- 手动触发懒加载(需在事务内):
内容的提问来源于stack exchange,提问作者Charlie
相关产品推荐
相关产品推荐

