2009-11-05 40 views
8

Quiero añadir una izquierda unirse en la tabla de tareas cuando se produce la siguiente condición: LEFT JOIN FETCH INMEDIATA p en (t.id = p.task.id y p.applicationName en ('XXX'))Hibernate HQL: el uso de un complejo izquierda join fetch

Aquí está mi HQL consulta:

select 
      distinct t   
     from 
      TASK t 
     LEFT JOIN FETCH 
      SERVER ser 
       on t.id=ser.task_id 
     LEFT JOIN FETCH 
      APPLICATION app 
       on ser.id=app.server_id   
     LEFT JOIN FETCH 
      PROMPT p on (t.id = p.task.id and p.applicationName in ('XXX')) 
     where 
      t.id=ser.task.id 
      and ser.id=app.server 
      and app.name in ('XXX') 
     order by t.id 

consigo la siguiente excepción, probablemente debido a "sobre" la palabra clave:

java.lang.NoSuchMethodError: org.hibernate.hql.antlr.HqlBaseParser.recover(Lantlr/RecognitionException;Lantlr/collections/impl/BitSet;)V 

     at org.hibernate.hql.antlr.HqlBaseParser.queryRule(HqlBaseParser.java:771) 

¿Alguna idea?

class Task { 
    private String taskId; 
    private Set<ServerDetails> servers; 
} 

class ServerDetails { 
    private String id; 
    private Set<ApplicationDetails> applications; 
} 

class ApplicationDetails { 
    private String id; 
} 

    Class Prompt { 
     private String applicationName; 
    } 

¿Cómo puedo usar combinación izquierda ir a buscar usando mi condición p.applicationName en ('XXX')?

+0

La estructura de clases que ha publicado (supongo que hay anotaciones adecuadas en todas esas propiedades) no vincula 'Prompt' a ninguna otra clase. Tu SQL se une a 'Prompt' y' Task' a través de 'task_id' pero no hay propiedades que coincidan arriba. ¿'Task' es una propiedad en' Prompt'? ¿O viceversa? ¿Puedes aclarar? – ChssPly76

Respuesta

23

Hay varios problemas aquí:

  1. Su HQL que has publicado no es realmente HQL :-) Es hacia arriba SQL. Para HQL necesita usar asociaciones mapeadas para unir tablas. Vea a continuación una versión mejorada.
  2. Por lo que sé ON cláusula no es compatible con múltiples condiciones unidas entre paréntesis.
  3. NoSuchMethodError no es algo que Hibernate arrojaría :-) Es probable que tenga una versión anterior de antlr.jar en algún lugar de su classpath y se recoja en lugar de la que esperaba Hibernate. Encuéntralo y quítalo.

Sin ver las asignaciones de los siguientes es probable inexacta, pero voy a tomar una puñalada en la redacción del HQL más apropiado:

select distinct t   
    from TASK t 
    left join fetch t.server ser 
    left join fetch ser.application app 
    left join t.prompt p with p.applicationName in ('XXX') 
order by t.id 

Tenga en cuenta que prompt no es exagerado porque no se puede utilizar join fetch junto con with condición. Puede reemplazarlo con inner join fetch y where si la asociación es obligatoria.

Si aún tiene problemas después de que se resuelva el problema de classpath, no dude en publicar sus asignaciones si necesita ayuda con HQL real.

+0

@ ChssPly76: estoy sorprendido de lo bien que conoces las entrañas de Hibernate, supongo que debes haber estado trabajando desde el principio o realmente has codificado el proyecto o ambos: de cualquier manera es genial tenerte aquí para iluminar las masas codificadoras –

+1

Ahora, harás que Gavin se ponga celoso. Estoy bromeando, por supuesto :-) - gracias. – ChssPly76

+0

Gracias por su respuesta, pero aún necesito obtener el prompt. ¿Cómo puedo utilizar left join ** fetch ** usando mi condición p.applicationName in ('XXX')? – Keren

Cuestiones relacionadas