2017-09-13 33 views
3

給定一個帶有OneToOne關係這兩個實體(A爲持有端保持在B實體ID):JPA懶惰的OneToOne關係是否在加載或查詢實體時提取?爲什麼?

@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的裝載性能方面的原因,這是爲什麼標準獲取它們呢?

更新:試圖簡化問題我剛剛加載了其中一個實體bRepository.findOne(bId),並且發生了同樣的情況。所以這不是關於標準,而是關於映射。它出什麼問題了?

+0

的可能的複製[使一個OneOne-關係懶惰](https://stackoverflow.com/questions/1444227/making-a-onetoone-relation-lazy) –

回答

1

這是真正爲我工作,公認的參考答案沒有:

就不得不更新我的Bentity實施FieldHandler,無非是需要:

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

    @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; 

    public AEntity getA() { 
     if (fieldHandler != null) { 
      return (AEntity) fieldHandler.readObject(this, "a", a); 
     } 
     return notificacion; 
    } 

    public void setA(AEntity a) { 
     if (fieldHandler != null) { 
      this.a = (AEntity) fieldHandler.writeObject(this, "a", this.a, 
         a); 
      return; 
     } 
     this.a = a; 
    } 

}