@Entity
@Getter
@Setter
@ToString
@Table(name = "order")
public class Order {
@Id
private Long id;
@Column(name = "account_id")
private Long accountId;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "account_id", insertable = false, updatable = false)
private Account account;
}
@Entity
@Getter
@Setter
@ToString
@Table(name = "account")
@SQLDelete(sql = "update account set is_deleted=1 where id=?")
@Where(clause = "is_deleted=0")
public class Account {
@Id
private Long id;
private String account;
@Column(name = "is_deleted")
private Boolean deleted;
}
如上2个实体类
问题1:查询Order的时候,最后生成的SQL语句不是JOIN连表查询,而是分两步,先查order再通过account_id去account表里查,这样会产生N+1的问题,不是只有懒查询才会这样吗?
问题2:Account使用了软删除,通过@Where(clause = "is_deleted=0")注解,每次查询的时候都会带上这个条件。那么如何可以设置例外呢,比如查询Order并关联查Account这种情况,如果带上这个条件,会出现EntityNotFoundException异常,原因是account里有记录被软删除了。
问题1已经招到解决办法了,放上来分享下
通过@NamedEntityGraph和@EntityGraph两个注解来实现
在Order类上增加注解
然后在对应Repository的查询方法上增加注解@EntityGraph
例如:
这样最后生成的查询语句使用的就是LEFT JOIN了,解决了N+1的问题