Tengo un Gato de clase y un Dueño de clase. Un gato tiene un propietario, pero un propietario puede tener muchos gatos. Lo que quiero consultar es obtener todos los propietarios que tienen un gato con ojos azules.

class Cat {
    Owner owner; //referenced from Owner.id
    String eyeColor;
}

class Owner {
    List<Cat> catList;
}

He probado algunos códigos pero la verdad, no sé qué hacer.

Criteria criteria = getCurrentSession().createCriteria(cat.getClass(), "cat");
criteria.createAlias("cat.owner", "owner");    
criteria.add(Restrictions.eq("cat.eyeColor", "blue");
  • Es la asociación bidireccional? ¿Por qué no utilizar HQL para tal estática de la consulta?
  • lo siento, pero no tengo elección como el uso de HQL.
  • Es la asociación bidireccional? ¿Por qué no tienen la opción? Eso es como un carpintero no se permite el uso de un martillo!
  • He editado. No es mi decisión, lo siento.
  • Mostrar los POJOs.
  • no se puede utilizar el HQL en caso de que la consulta es demasiado complejo, su mejor escribir los criterios de consulta, también se encarga de todos los tipos de conversiones, como la conversión de tipo localDate a la zona horaria de formato , etc. Escrito HQL es un dolor en el culo, sobre todo si tiene 100s de los filtros de la consulta para la cláusula where, el código administrado forma de escribir consultas largas y sencillo de mantener en el largo plazo.

InformationsquelleAutor hellzone | 2013-07-17

2 Comentarios

  1. 43

    Criterios sólo puede seleccionar las proyecciones, o la entidad raíz. No se unió a la entidad. Algunas de las consultas son por lo tanto imposible de expresar con Criterios (lo cual es una buena razón para utilizar HQL, además de mucho mejor legibilidad y la concisión).

    No todo está perdido aquí, aunque, debido a su asociación es bidireccional. Tan sólo necesita el equivalente de la consulta HQL

    select distinct owner from Owner owner 
    join owner.cats cat 
    where cat.eyeColor = 'blue'

    Que es

    Criteria c = session.createCriteria(Owner.class, "owner");
    c.createAlias("owner.cats", "cat");
    c.add(Restrictions.eq("cat.eyeColor", "blue");
    c.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY);
    • En mi caso, el gato conoce al dueño, pero el dueño no sabe acerca de sus gatos. ¿Cómo sería la criteriaquery parece?
    • Como dije en mi respuesta, AFAIK (a menos que la hicieron posible en las versiones más recientes), no es posible el uso de criterios. Uso HQL, o el uso de la JPA2 criterios de la API.
    • Esto hace de la memoria «distinta» a la operación. Si un propietario tiene un millón de discos blu-los ojos de los gatos, recuperará todos ellos de la base de datos, sólo para encontrar el único propietario (el ejemplo no es, probablemente, el askers caso real, usted no sabe el verdadero cardinalidad). Ver mi respuesta como la forma en que se podría hacer en la base de datos.
    • en su memoria, pero se hace el truco, pero espero que se podría haber hecho a través de la consulta sin el uso de HQL, pero se ve como hibernate no lo admite
  2. 4

    Intente esto:

    DetachedCriteria dc = DetachedCriteria.forClass(Cat.class, "inner")
        .add(Restrictions.eq("eyeColor", "blue"))
        .add(Restrictions.eqProperty("inner.owner", "outer.id"));
    
    session.createCriteria(Owner.class, "outer")
        .add(Subqueries.exists(dc))
        .list();

    Esto puede utilizar el índice en la base de datos y no en la memoria distinct operación como en el @JB Nizet de la versión (ver mi comentario allí). El índice será:

    CREATE INDEX idx_cat_owner_eyecolor ON Cat(fkOwner, eyeColor)

    Pensar distinct operación (ya sea en SQL o en la memoria) como de un código de olor. Rara vez se usa, y muchos programadores principiantes se utiliza para corregir el problema «¿por qué tengo esta fila dos veces». Casi siempre puede reescribirse como en este caso. Los casos de uso, cuando es necesario, son pocos.

    • en exterior.pk, ¿qué es pk?
    • esta consulta no funciona y lanza la excepción de puntero nulo.. JBNizet la consulta está trabajando bien. aunque sé que no es exactamente una consulta de la base de código distinto de no consulta basada distintas, pero al menos funciona.
    • podrías compartir la NPE de la traza de la pila? Yo creo que usted hizo algún otro error. outer.pk es la clave principal, tal vez debería haber usado outer.id, he editado

Dejar respuesta

Please enter your comment!
Please enter your name here