2017-09-13 3 views
3

Compte tenu de ces deux entités ayant une relation de OneToOne (A comme côté propriétaire de tenir l'identifiant de l'entité B):JPA paresseux OneToOne relation est récupérée lors du chargement ou l'interrogation d'une entité alors qu'elle ne devrait pas? Pourquoi?

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

} 

J'utilise une requête de critères pour obtenir toutes les entités B dans une date donnée:

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])); 
       } 
      } 
     }; 
    } 
} 

la requête est exécutée avec bRepository.findAll(BSpecification.filter(filter)); et je vois que, après celui d'obtenir BEntities en fonction de la date ...

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)<=? 

... il y a un autre sur e qui obtient le AEntity one-to-one-paresseusement liés:

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

Pour des raisons de performance que je dois empêcher le chargement de AEntities, pourquoi est-ce critère les chercher? MISE À JOUR: En essayant de simplifier le problème, je viens de charger l'un des BEntities bRepository.findOne(bId) et la même chose se produit. Donc, il ne s'agit pas des critères mais de la cartographie. Qu'est ce qui ne va pas avec ça?

+0

double possible de [ Rendre une relation OneToOne paresseuse] (https://stackoverflow.com/questions/1444227/making-a-onetoone-relation-lazy) –

Répondre

1

C'est ce qui en fait travaillé pour moi, la réponse n'a pas accepté référencé:

juste eu à mettre à jour mon Bentity à mettre en œuvre FieldHandler, rien de plus que ce qui est nécessaire:

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

}