2011-10-19 6 views
10

Sono consapevole che è possibile utilizzare {alias} per riferirsi al soggetto principale all'interno di uno SQLProjection:Riferimenti a criteri esterni interrogare gli alias all'interno di uno SQLProjection

Projections.sqlProjection("MIN({alias}.field) as value", new String[]{"value"}, new Type[]{new LongType()})) 

Quello che sto cercando di fare è di riferimento un alias per un non root entità:

Projections.sqlProjection("MIN(i.powerRestarts) as value", new String[]{"value"}, new Type[]{new LongType()})) 

dove i è un alias dalla query criteri esterno. Il codice sopra genera un'eccezione SQL che dice che non è possibile trovare i.powerRestarts.

È possibile fare riferimento a un alias non root da un progetto SQL?

risposta

12

Avendo fatto qualche ricerca su google, sembra che questo non sia possibile - Hibernate consente solo l'inclusione dell'alias di root usando {alias} nella stringa SQL di SQLProjection. Ho comunque trovato this issue regarding the limitation sulle pagine di Hibernate JIRA.

Qualcuno ha gentilmente inviato una patch che consente l'utilizzo di alias non root nella stringa SQLProjection, attraverso una nuova classe RestrictionsExt. Usando il mio esempio dalla domanda:

Projections.sqlProjection("MIN(i.powerRestarts) as value", new String[]{"value"}, new Type[]{new LongType()})) 

L'alias i può ora essere fatto riferimento come:

RestrictionsExt.sqlProjection("MIN({i}.powerRestarts) as value", "value", new LongType()) 

ho dovuto modificare il metodo statico RestrictionsExt.sqlProjection per consentire specificazione del tipo per l'alias di colonna ("value") (qui definito come LongType), poiché la patch non lo consentiva e veniva impostato su StringType.

La classe SQLAliasedProjection nella patch richiede anche l'accesso ai seguenti metodi privati ​​in org.hibernate.loader.criteria.CriteriaQueryTranslator: getOuterQueryTranslator e getAliasedCriteria. Per arrivare a questo lavoro senza modificare la fonte di Hibernate, ho usato riflessione:

cri = ((org.hibernate.loader.criteria.CriteriaQueryTranslator) criteriaQuery).getAliasedCriteria(alias); 

è stato cambiato a:

Method m = ((org.hibernate.loader.criteria.CriteriaQueryTranslator) criteriaQuery).getClass().getDeclaredMethod("getAliasedCriteria", String.class); 
m.setAccessible(true); 
cri = (Criteria) m.invoke(((org.hibernate.loader.criteria.CriteriaQueryTranslator) criteriaQuery), alias); 

Speriamo che questo vi aiuterà a chiunque altro di fronte lo stesso problema.

Problemi correlati