-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 11 posts ] 
Author Message
 Post subject: JOIN with Criteria
PostPosted: Fri Dec 03, 2010 6:45 am 
Beginner
Beginner

Joined: Sun Aug 13, 2006 8:40 am
Posts: 28
I am getting an information overload and cannot find the answer to this question:

I would like to use a criteria with restrictions on the columns of the bags the persistent class has collections of. Is this possible? If so, how can this be done?

Explanation:
A persistent class A has a primary key (A.getId()) and a collections of the persistent class B.
The persistent class B has a collection of the persistent class C.
The persistent class C has a property telling if it is deleted (C.isDeleted())

This is what I would like to achieve:
I would like to get the instance of A where A.getId() equals the primary key I am looking for.
I want to join the collections of B and C.
I do not want to receive any instances where C.isDeleted() == true

Anyone?


Top
 Profile  
 
 Post subject: Re: JOIN with Criteria
PostPosted: Fri Dec 03, 2010 11:03 am 
Newbie

Joined: Wed Sep 22, 2010 12:01 pm
Posts: 7
Criteria criteria = session().createCriteria(A.class);

criteria.add(Restrictions.eq("id", [your value]);

criteria.createAlias([name of the field of your collection of B in the A class], "colB");
criteria.createAlias("colB." + [name of the field of your collection of C in the B class], "colC");

criteria.add(Restrictions.eq("colC.deleted", Boolean.FALSE);


Top
 Profile  
 
 Post subject: Re: JOIN with Criteria
PostPosted: Mon Dec 06, 2010 5:04 am 
Beginner
Beginner

Joined: Sun Aug 13, 2006 8:40 am
Posts: 28
I am sorry... I cannot get this to work. I will give you my needs as it is a bit more complicated than my example...

I have a Customer. This customer has a collection of the entity Contract and a collection of CustomerData (more information on the customer). Each contract as a collection of the data for the contract (ContractData). The contract data in turn has a collection of the Entity Product which it represent.

What I want:
I want the customer for who I have the primary key. Then I want to eager fetch the customer data and I want to join the contracts on this customer. I also want to join the contract data on each contract (if the property historicDate is null). I finally want to join the products on the contract data if the property isDeleted is null or false.

This is my code which do not work :(
Code:
        Criteria criteria = session().createCriteria(Customer.class) //
                .add(Restrictions.eq("id", customerId)) //
                .setFetchMode("contracts", FetchMode.JOIN) //
                .setFetchMode("customerData", FetchMode.SELECT) //
                .createAlias("contracts", "c") //
                .setFetchMode("c.contractData", FetchMode.JOIN) //
                .createAlias("c.contractData", "cd") //
                .add(Restrictions.isNull("cd.historicDate")) //
                .setFetchMode("cd.product", FetchMode.JOIN) //
                .createAlias("cd.product", "p") //
                .add(Restrictions.not(Restrictions.eq("p.isDeleted", true)));


This criteria returns null and no customer.... Anyone?


Top
 Profile  
 
 Post subject: Re: JOIN with Criteria
PostPosted: Mon Dec 06, 2010 7:15 am 
Beginner
Beginner

Joined: Wed Jan 07, 2009 7:07 pm
Posts: 26
Hi,

Can you post your required SQL along with your mapping files ?

Thanks
-Vishal


Top
 Profile  
 
 Post subject: Re: JOIN with Criteria
PostPosted: Mon Dec 06, 2010 8:12 am 
Beginner
Beginner

Joined: Sun Aug 13, 2006 8:40 am
Posts: 28
required sql? you want the generated sql?

generated sql:
Code:
    select ...
    from
        CUSTOMER this_
    inner join
        CONTRACT c1_
            on this_.CUSTOMER_ID=c1_.CUSTOMER_ID
    inner join
        CONTRACT_DATA cd2_
            on c1_.CONTRACT_ID=cd2_.CONTRACT_ID
    inner join
        PRODUKT p3_
            on cd2_.CUSTOMER_DATA_ID=p3_.CUSTOMER_DATA_ID
    left outer join
        CUSTOMER customer8_
            on c1_.CUSTOMER_ID=customer8_.CUSTOMER_ID
    where
        this_.CUSTOMER_ID=?
        and cd2_.DAT_HISTORISK is null
        and not p3_.DELETED=?


I do not use mapping files, but annotations:
Code:
@OneToMany(cascade = CascadeType.ALL, mappedBy = "customer")
private List<Contract> contracts = new ArrayList<Contract>(); // on customer
@OneToMany(cascade = CascadeType.ALL, mappedBy = "contractId")
private List<ContractData> contractData = new ArrayList<ContractData>(); // on contract
@OneToMany(cascade = CascadeType.ALL, mappedBy = "contractDataId")
private List<Product> products; // on contract data


In other criteria I write, the restrictions on the collections do not restrict the result returned. Is there some "magic" I need to specify on the session factory or something?

this is very frustrating... please help...


Top
 Profile  
 
 Post subject: Re: JOIN with Criteria
PostPosted: Mon Dec 06, 2010 9:33 am 
Newbie

Joined: Tue Sep 21, 2004 11:21 am
Posts: 8
try building your query step by step.

remove all criteria. do you get a result?
ad one, and check the result.

after done the above... can you tell where it goes wrong?


Top
 Profile  
 
 Post subject: Re: JOIN with Criteria
PostPosted: Mon Dec 06, 2010 10:08 am 
Beginner
Beginner

Joined: Sun Aug 13, 2006 8:40 am
Posts: 28
I have the following criteria:
Code:
        Contract contract = (Contract) createCriteria(Contract.class) //
                .add(Restrictions.eq("id", 1L)) //
                .setFetchMode("contractData", FetchMode.JOIN) //
                .createAlias("contractData", "cd") //
                .add(Restrictions.isNull("cd.historicDate")) //
                .setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY) //
                .uniqueResult();


which generates the following sql:
Code:
   select ... from
        CONTRACT this_
    inner join
        CONTRACT_DATA cd1_
            on this_.CONTRACT_ID=cd1_.CONTRACT_ID
    left outer join
        CUSTOMER customer4_
            on this_.CUSTOMER_ID=customer4_.CUSTOMER_ID
    where
        this_.CONTRACT_ID=?
        and cd1_.HISTORIC_DATE is null


It generates an outer join on the Contract.customer relation.

How does the where clause restrict the result when there is one join and one outer join? The customer relationship is not specified in the criteria...

I get a result from this criteria, but the Contract.contractData.size should be one, but is two. the CustomerData.historicDate criteria is not regarded.


Last edited by jactor on Mon Dec 06, 2010 12:02 pm, edited 1 time in total.

Top
 Profile  
 
 Post subject: Re: JOIN with Criteria
PostPosted: Mon Dec 06, 2010 11:51 am 
Beginner
Beginner

Joined: Sun Aug 13, 2006 8:40 am
Posts: 28
... it seems that the restrictions are disregarded when I am using Contract.getContractData()

... then a new sql is generated with no restrictions.

... so when I call getContractData(), this sql is generated:
Code:
select ... from
        CONTRACT_DATA contractData0_
    where
        contractDato0_.CONTRACT_ID=?


all joins and restrictions are disregarded... I am now very frustrated...


Top
 Profile  
 
 Post subject: Re: JOIN with Criteria
PostPosted: Tue Dec 07, 2010 7:40 am 
Beginner
Beginner

Joined: Sun Aug 13, 2006 8:40 am
Posts: 28
The following HQL is doing what I try to achieve by criteria:
Code:
        String queryString = "select distinct contract\n" + //
                "from Contract as contract\n" + //
                " inner join fetch contract.contractData as contractData\n" + //
                "where contract.id = :CONTRACT_ID\n" + //
                "and contractData.historicDate is null";


If I remove the fetch statement from the hql, it will behave as the criteria does. The javadoc of the FetchMode.JOIN says that it will do the same as an eager fetch.

Am I missing something?


Top
 Profile  
 
 Post subject: Re: JOIN with Criteria
PostPosted: Tue Dec 07, 2010 11:51 am 
Beginner
Beginner

Joined: Sun Aug 13, 2006 8:40 am
Posts: 28
I am stuck with the problem already mentioned and want to attack the problem from a different angle.

Can you take a relationship (customer.getContract().getContractData()) and refresh this dependency using some form of criteria?

A small part is resolved using hql (contract.getContractData()), but when I try writing the hql on the full object graph (customer.getContract().getContractData()), then hibernate returns an error saying it cannot fetch multiple bags.

So I hope I can fetch the entity which I am looking for and then refresh the dependencies with some sort of criteria. Is there any way I can achieve this?


Top
 Profile  
 
 Post subject: Re: JOIN with Criteria
PostPosted: Wed Dec 08, 2010 9:21 am 
Beginner
Beginner

Joined: Sun Aug 13, 2006 8:40 am
Posts: 28
It seems that I have misunderstood what Criteria is supposed to do.

With Criteria you can set restrictions on the result you search for, but it do not enforce those restrictions on the model which is returned by the criteria search. With hql one can restrict the search result.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 11 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.