Given these two entities with a OneToOne relationship (A as owning side holding the B entity 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;
}
I use a criteria query to get all B entities within a given date:
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]));
}
}
};
}
}
The query is executed with bRepository.findAll(BSpecification.filter(filter));
and I see that after the one to get BEntities based on the 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)<=?
... there is another one that gets the one-to-one-lazily-related AEntity:
select
a0_.id as id1_9_2_,
a0_.b_id as b14_9_2_,
from
a a0_
where
a0_.b_id=?
Due to performance reasons I need to prevent the loading of AEntities, why is this criteria fetching them?
UPDATE: Trying to simplify the problem I have just loaded one of the BEntities bRepository.findOne(bId)
and the same happens. So it's not about the criteria but about the mapping. What's wrong with it?
This is what actually worked for me, the accepted referenced answer didn't:
Just had to update my Bentity to implement FieldHandler, nothing more than that needed:
@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;
}
}