2015-01-12 6 views
6

Abbiamo un oggetto multimediale:recupero Eager in una primavera Specification

public class Media implements Serializable { 

    @Id 
    @GeneratedValue(strategy = IDENTITY) 
    @Column(insertable = false, updatable = false) 
    private Long id; 
    // other attributes 
    @ManyToOne(fetch = FetchType.EAGER) 
    @JoinColumn(name = "channelId", referencedColumnName = "id") 
    private Channel channel; 
    // getters, setters, hashCode, equals, etc. 

}

La desiderosi fetch genitore canale lavora a metodi repository regolari, ma non quando si utilizza una specifica.

Ecco lo Specification:

public class MediaSpecs { 

public static Specification<Media> search(final Long partnerId, final Integer width, final Integer height, 
     final String channelType) { 

    return new Specification<Media>() { 

     @Override 
     public Predicate toPredicate(Root<Media> root, CriteriaQuery<?> query, CriteriaBuilder cb) { 
      Predicate restrictions = cb.equal(root.get("archived"), false); 
      // other restrictions are and-ed together 
      if (channelType != null) { 
        Join<Media, ChannelType> join = root.join("channel").join("orgChannelType").join("type"); 
       restrictions = cb.and(cb.equal(join.get("type"), channelType)); 
      } 
      return restrictions; 
     } 
    }; 
} 

La "ricerca" spec funziona correttamente quando viene specificata ChannelType, quindi il join sta lavorando. Come posso specificare che i join debbano essere recuperati con entusiasmo?

Ho provato ad aggiungere

Fetch<Media, ChannelType> fetch = root.fetch("channel").fetch("orgChannelType").fetch("type"); 

Poi Hibernate genera un'eccezione:

org.hibernate.QueryException: interrogazione specificata unirsi recupero, ma il proprietario dell'associazione scaricata non era presente nella lista di selezione [ FromElement {esplicito, non un join di raccolta, preleva join, recupera proprietà non pigri, classAlias ​​= generatoAlias4 ...

Come aggiungere le associazioni all'elenco di selezione?

Grazie.

risposta

6

Penso che tu abbia problemi con la query di conteggio. Di solito la specifica è utilizzata per query di dati e query di conteggio. E per query di conteggio non c'è "Media". Io uso questa soluzione:

Class<?> clazz = query.getResultType(); 
if (clazz.equals(Media.class)) { 
    root.fetch("channel"); 
} 

Questo utilizzo recupera solo per query di dati non per query di conteggio.

0

Ad esempio:

public Predicate toPredicate(Root<Person> root, CriteriaQuery<?> query, CriteriaBuilder cb) { 
       if (Long.class != query.getResultType()) { 
        root.fetch(Person_.addresses); 
       } 
       return cb.conjunction(); 
      } 
+0

pl spiegare la tua risposta –

+0

verifico se questa è una query di conteggio (risultato Long.class) poi ho appena ignorare un download aderire – Eugene