问题产生:使用SpringBoot 测试模块测试Spring-Data-JPA @OneToMany(一对多)关系查询时,提示如下错误信息:
控制台JPA 执行sql 输出:
Hibernate: select author0_.id as id1_2_0_, author0_.name as name2_2_0_, articlelis1_.author_id as author_i4_1_1_, articlelis1_.id as id1_1_1_, articlelis1_.id as id1_1_2_, articlelis1_.author_id as author_i4_1_2_, articlelis1_.content as content2_1_2_, articlelis1_.title as title3_1_2_ from author author0_ left outer join article articlelis1_ on author0_.id=articlelis1_.author_id where author0_.id=?根据Debug模式,代码错误最终定位在com.zzg.entity.Article.toString() 方法,堆栈相关信息如上截图。
结合google 结果,分析结果如下:System.out.println("author=" + author);会调用Author类中toString()方法,toString()方法会触发author属性的懒加载,便会去调用Article类的toString()方法,Article()类中的toString()方法,会触发articleList属性的懒加载,接着会调用Author类中的toString()方法。以上就是循环引用的过程。
解决办法:将@Data注解去掉,换成@Setter、@Getter、@EqualsAndHashCode注解。我们自己重写Article类的toString()方法。
package com.zzg.entity; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.Table; import lombok.AllArgsConstructor; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; import lombok.experimental.Accessors; @Entity @Table(name = "article") @Setter @Getter @EqualsAndHashCode// 自动生成get、set、toString、equals方法 @AllArgsConstructor // 全参构造方法 @NoArgsConstructor // 无参构造方法 @Accessors(chain = true) // 链式编程 public class Article { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) // 自增长策略 private Long id; @Column(nullable = false, length = 50) // 映射为字段,值不能为空 private String title; @Column(nullable = false) // 映射为字段,值不能为空 private String content;//文章全文内容 //可选属性optional=false,表示author不能为空。删除文章,不影响用户 @ManyToOne(cascade={CascadeType.MERGE,CascadeType.REFRESH},optional=false) @JoinColumn(name="author_id")//设置在article表中的关联字段(外键) private Author author;//所属作者 @Override public String toString() { // TODO Auto-generated method stub return "Article{ id='"+id+"'}"; } }SpringBoot 测试代码:
@Test public void selectOneToMany(){ Author author = authorRepository.findOne(10L); System.out.println("author=" + author); }效果截图:
