example ejemplo addorder java sql hibernate criteria many-to-many

java - ejemplo - Consulta de la relación ManyToMany con los criterios de Hibernate



hibernate criteria hql restriction (5)

Aún puede usar la notación de puntos para trabajar en las relaciones. Por ejemplo, suponiendo que tiene una propiedad DriversLicence.licenceClass y una propiedad LicenceClass.type, entonces:

session.createCriteria(DriversLicence.class) .add(Expression.or( Expression.eq("licenceClass.type", "Car"), Expression.eq("licenceClass.type", "Motorbike") ) ).list();

Personalmente, simplemente evitaría usar criterios en este caso porque no es una consulta dinámica, sino que usaré:

session.createQuery("from DriversLicence where licenceClass.type in (:types)") .setParameterList("types", myListOfTypes) .list();

No estoy seguro de cómo describir este problema, así que creo que un ejemplo es la mejor manera de hacer mi pregunta:

Tengo dos tablas con una relación manyToMany:

DriversLicence <-> LicenceClass

LicenceClass es cosas como "Coche", "Moto" y "Medio rígido".

Al utilizar Hibernate Criteria, ¿cómo puedo encontrar todas las licencias que tienen LicenceClasses "Car" y "Motorbike"?

ACTUALIZACIÓN 12/11/2008 Descubrí que esto se puede lograr fácilmente utilizando un ResultTransformer personalizado. Sin embargo, el problema es que un transformador de resultados solo se aplica DESPUÉS de que la consulta devuelva sus resultados, en realidad no se convierte en parte del SQL. Así que supongo que mi pregunta ahora es "¿Puedes hacer lo que inicialmente describí en SQL, y hay un análogo de Hibernate Criteria?"


''No creo que esto vaya a funcionar. Quiero encontrar todas las licencias que tengan tanto "Coche" como "Moto"

User Expression.and (....) en lugar de Expression.or (....) en el fragmento provisto por Nick


Tuve un problema similar pero arreglé usando HQL, tengo una clase "Enterprise" que está relacionada con la clase "User" y también relacionada con la clase "Role", tienen una relación de muchos a muchos, cuando necesito todas las empresas relacionadas a un usuario específico, hago lo siguiente;

Select e from Enterprise As e inner join e.Users As u inner join u.Roles As r Where u.UserCode=?

Supongo que en tu caso deberías hacer algo como;

Select dl from LicenceClass As l inner join l.DriversLicences As dl Where l.LicenseClass.Name = ? OR l.LicenseClass.Name=? OR l.LicenseClass.Name=?

Espero eso ayude.


Otra opción es encadenar uniones (una unión por cada LicenseClass). Utilicé el generador de criterios y predicados como este

List<Predicate> predicates = new ArrayList<>(); for(Integer lcId : licenceClassIdList) { SetJoin<DriversLicence, LicenceClass> dlClasses = dlRoot.join(DriversLicence_.licenceClasses); predicates.add(builder.equal(dlClasses.get(LicenseClass_.id), lcId)); } Predicate predicate = builder.and(predicates.toArray(new Predicate[predicates.size()]));

Observe que dlRoot es un objeto de la clase raíz y puede obtenerlo de la clase CriteriaQuery. El predicado resuelto es lo que estás buscando ...


Así es como finalmente lo logré usando HQL:

public List<DriversLicence> findDriversLicencesWith(List<LicenceClass> licenceClasses) { String hqlString = "select dl from DriversLicenceImpl dl where 1=1 "; for (int i = 0; i < licenceClasses.size(); i++) { hqlString += " and :licenceClass" + i + " = some elements(dl.licenceClasses)"; } Query query = getSession().createQuery(hqlString); for (int i = 0; i < licenceClasses.size(); i++) { query.setParameter("licenceClass" + i, licenceClasses.get(i)); } return query.list(); }

O usando los criterios de Hibernate con una sqlRestriction:

for (LicenceClass licenceClass : licenceClasses) { criteria.add(Restrictions.sqlRestriction("? = some(select " + LicenceClass.PRIMARY_KEY + " from " + LICENCE_CLASS_JOIN_TABLE + " where {alias}." + DriversLicence.PRIMARY_KEY + " = " + DriversLicence.PRIMARY_KEY + ")", licenceClass.getId(), Hibernate.LONG)); }

LICENCE_CLASS_JOIN_TABLE es el nombre de la tabla que hibernate genera para admitir la relación many-to-many entre driversLicence y LicenceClass.