简体   繁体   中英

jpql left join fetch not returning results for like

In a spring mvc app using hibernate and MySQL, I have written the following query method to return a list of names with patients:

@SuppressWarnings("unchecked")
public Collection<Person> findPersonByLastName(String ln) throws DataAccessException{
    Query query = this.em.createQuery("SELECT DISTINCT pers FROM rimPerson pers left join fetch pers.names nm WHERE nm.family LIKE :lnm");
    query.setParameter("lnm", ln);
    return query.getResultList();
}

This is producing the following hibernate sql:

Hibernate: 
select distinct
 person0_.hppid as hppid1_340_0_,
 names1_.HJID as HJID1_89_1_,
 person0_2_.classCode_HJID as classCod2_339_0_,
 person0_1_.administrativeGenderCode_HJID as administ2_341_0_,
 person0_1_.birthTime_HJID as birthTim3_341_0_,
 names1_.DELIMITER_ as DELIMITE2_89_1_,
 names1_.FAMILY as FAMILY3_89_1_,
 names1_.named_entity_hppid as named5_89_1_,
 names1_.SUFFIX as SUFFIX4_89_1_,
 names1_.name_entity_HJID as name9_340_0__,
 names1_.HJID as HJID1_89_0__
 from
 rim_person person0_ inner join rim_living_subject person0_1_ on person0_.hppid=person0_1_.hppid
 inner join rim_entity person0_2_ on person0_.hppid=person0_2_.hppid
 inner join rim_infrastructure_root person0_3_ on person0_.hppid=person0_3_.hppid
 left outer join EN names1_ on person0_.hppid=names1_.name_entity_HJID
 where names1_.FAMILY like ?

When I call the above jpql method with the following command, it returns zero results:

this.myappService.findPersonByLastName("");  

I also get zero results when I cut and past the above generated hibernate code into the MySQL command line client and replace ? with '' .

If, however, I remove the where names1_.FAMILY like ? from the hibernate generated sql above and place the shortened sql into the MySQL command line client, I get four results, eachof which has a value for the lastname field.

How can I change the jpql so that it generates a hibernate query that returns the four results when `` is passed as the empty string parameter? I want the result set to include every result when the user gives empty input, but to give filtered results when the user types in any given text input.

The typical reason that like fails to do what you think it ought to do is to forget to put a wildcard in the pattern string. For example, if you want to match all user names that begin with 'Code' you must do something like name like 'Code%' , NOT name like 'Code' . You can control exactly what your predicate matches with careful placement of % s in your string.

Try this to see all entities no matter what the value in family:

this.myappService.findPersonByLastName("%");

It is kinda cheesy to have the caller of findPersionByLastName have to put in the % wildcard. A better implementation is to have the caller specify which last name they are looking for, and then have the code that constructs the query put the wildcard in the right place. When you are looking for last names, you might do something like this:

query.setParameter("lnm", "%" + ln);

That would match anything that ends with the parameter that is passed to the method.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM