开发者

hibernate hql how to get matched child from parent?

开发者 https://www.devze.com 2023-03-30 07:59 出处:网络
two tables, Cat and kitten(one to many), there are 5 records in the kitten table, and 1 in the cat table. kitten have color, 2 in white and 3 in yellow. I wrote the following HQL which return the Cat.

two tables, Cat and kitten(one to many), there are 5 records in the kitten table, and 1 in the cat table. kitten have color, 2 in white and 3 in yellow. I wrote the following HQL which return the Cat.

select c from Cat c inner join c.kitten k where k.color='yellow'

this return me the cat. but when I did

cat.getKitten().size() 

it returns 5, instead of 3. what I want to do is only get the matched child instead of all of them, what's the right way to do this?

seems like this do the trick, thanks zzz and everyone's effort

Session session = sessionFactory.getCurrentSession();
      开发者_如何学运维  List<Object> funds = session.createQuery("select k.cat,k from kitten k where k.color='yellow'").list();
        Object[] os = (Object[])funds.get(0);
        Cat c = (Cat)os[0];
        Kitten fc = (Kitten)os[1];
        List list = new ArrayList<Kitten>();
        list.add(fc);
        c.setKittens(list);

this return the right thing.


In short, you don't want to select the cat, but want to select some of its kittens:

select k from Cat c inner join c.kitten k where k.color = 'yellow'

This will select 3 kitten, each having the same cat.


The query asks for all the cats with yellow kittens, but once you have the cat, you are then asking for all its associated kittens (not just the yellow ones).

We might be able to help you more if you show how you have mapped/annotated the Cat/Kitten classes.


btw that is by design. You can't filter a collection by using a restriction.

If you look closer, hibernate is going to the DB twice: once with your query, and once to get the collection.

you need to get your cat object first and then get the filtered kittens which will be lazyloaded by default.

something like

var kittens= cat.kittens.where(x->x.color="yellow")
var count=kittens.Count();

if java you could do something like this

Collection<Kitten> kittens= cat.getKittens();
Collection<Kitten> filteredKittens = filterCollection(kittens, session);

and your filterCollection method will be:

private static <T> Collection<T> filterCollection(Collection<T> collection, Session s) {
        Query filterQuery = s.createFilter(collection, "where this.color='yellow'");
        return filterQuery.list();
    }

here is a blogpost abt it: http://www.flexpasta.com/index.php/2009/05/20/filtering-hibernate-child-collections/

based on the comments below we decided to use

select g, k from grandCat g inner join fetch g.cat c inner join fetch c.kitten k where k.color ='yellow' 

and select the required content and then cast it appropriatelty.. read the comments for clarity

0

精彩评论

暂无评论...
验证码 换一张
取 消