问题 Spring Data JPA 使用findById(id),getOne(id),虽然数据库中存在记录,但查询不出来。
描述 最近升级项目框架,将Spring Boot版本升级至2.0.2。Spring Data JPA有不少变化,根据id查询 findOne(id)方法没有了,换成了findById(id),同时还有getOne(id)可以使用。
但使用新的根据id的查询方法找不到数据,虽然数据库中记录存在。
解决 查看sql日志发现新方法会将查询Entity中的关联Entity inner join进查询语句。示例如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 @Entity @Table(name = "app") @EqualsAndHashCode(callSuper = true) @Data @NoArgsConstructor @SequenceGenerator(name = "app_id_seq", sequenceName = "app_id_seq", allocationSize = 1) public class App extends SequenceIdentityEntity { private static final long serialVersionUID = -259135240342702789L ; @Id @Column(name = "id") @GeneratedValue(generator = "app_id_seq", strategy = GenerationType.SEQUENCE) private Integer id; @Column(name = "name") private String name; @ManyToOne(optional = false) @JoinColumn(name = "template_id", nullable = false) private Template template; @Column(name = "template_id", updatable = false, insertable = false) private Integer templateId; }
1 2 3 // 使用findById(id),getOne(id)时打印的sql select app0.id as id1_0_0, app0.name as name_2_0_0, template1.app_id as app_id5_4_1, template1.name as name6_4_1 from app app0_ inner join template template1_ on app0.template_id=template1.id where app0_.id=?
因此若关联值templateId为空或值映射不上 时,就会找不到app记录。
在@ManyToOne添加fetch = FetchType.LAZY即可解决问题,同理使用@OneToOne,@OneToMany等若不能保证 关联字段不为空且一定能找到关联数据 时,均需配置懒加载。
1 2 3 @ManyToOne(optional = false, fetch = FetchType.LAZY) @JoinColumn(name = "template_id", nullable = false) private Template template;