加载或查询实体时,如果不应该获取JPA lazy OneToOne关系?为什么?

时间:2017-09-13 11:03:09

标签: hibernate jpa spring-data spring-data-jpa jpa-criteria

鉴于这两个实体具有OneToOne关系(A作为拥有B实体ID的拥有方):

@Entity
@Table(name="A")
public class AEntity{

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer id;

    ...

    @OneToOne(optional = true, cascade = CascadeType.ALL)
    @JoinColumn(name = "bId")
    private BEntity b;

}

@Entity
@Table(name="B")
public class BEntity{

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer id;

    @OneToOne(mappedBy = "b", cascade = CascadeType.ALL, optional = true, fetch = FetchType.LAZY)
private AEntity a;
    ...

    @Temporal(TemporalType.TIMESTAMP)
    @Column(nullable = false)
    protected Date someDate;

}

我使用条件查询来获取给定日期内的所有B实体:

public class BSpecification {
    public static Specification<BEntity> filter(BFilter filter) {
        return new Specification<BEntity>() {
            @Override
            public Predicate toPredicate(Root<BEntity> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                List<Predicate> predicates = new ArrayList<Predicate>();
                if(filter.getDateFrom() != null){
                    predicates.add(cb.greaterThanOrEqualTo(cb.function("date", Date.class, root.get(BEntity_.someDate)),
                            filter.getDateFrom()));
                }
                if(filter.getDateTo() != null){
                    predicates.add(cb.lessThanOrEqualTo(cb.function("date", Date.class, root.get(BEntity_.someDate)), 
                            filter.getDateTo()));
                }
                if(predicates.size()==0){
                    return null;
                }else{
                    return cb.and(predicates.toArray(new Predicate[0]));
                }
            }
        };
    }
}

使用bRepository.findAll(BSpecification.filter(filter));执行查询,我看到根据日期获得BEntities后...

select
    b0_.id as id1_7_,
    b0_.some_date as some_date_cr2_7_,
from
    b b0_ 
where
    date(b0_.some_date)>=? 
    and date(b0_.some_date)<=?

......还有另一个获得与一对一懒惰相关的AEntity:

 select
    a0_.id as id1_9_2_,
    a0_.b_id as b14_9_2_,
from
    a a0_ 
where
    a0_.b_id=?

由于性能原因,我需要阻止加载AEntities,为什么这个标准会提取它们?

更新:尝试简化我刚刚加载其中一个BEntities bRepository.findOne(bId)的问题,同样的事情发生了。所以它不是关于标准,而是关于映射。怎么了?

1 个答案:

答案 0 :(得分:1)

这实际上对我有用,接受的参考答案没有:

只需更新我的Bentity以实现FieldHandler,只需要:

IF 1=0
BEGIN
   CREATE TABLE ##UserInfo (
      [UserId] int NOT NULL IDENTITY (1, 1),
      [strEmail] varchar(50)  NULL,
      [strLastName] varchar(50)  NULL,
      [strFirstName] varchar(50)  NULL,
   );
END