-->
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.  [ 5 posts ] 
Author Message
 Post subject: Writing Criteria for Conjunction in a collection
PostPosted: Fri Jan 27, 2006 1:39 pm 
Newbie

Joined: Fri Apr 08, 2005 6:26 am
Posts: 6
Location: Edinburgh, UK
I have a class with a many-to-many association(implemented using many-to-one associations and an intermediary class.) i.e.

Product <-> ProductMetaData <-> MetaData

I'm trying to write a Criteria that selects Products that have a pre-defined set of MetaData, and I'm not having any luck.

I have the following sql. (Probably not very efficient/elegant due to my inexperience with SQL, but it does seem to work.)

Code:
select p.product_id from product p, product_validation_data pvd0, product_validation_data pvd1 where p.product_id=pvd0.product_fk and p.product_id=pvd1.product_fk and pvd0.metadata_fk=4 and pvd1.metadata_fk=5;


I've tried a number of scenarios, mostly resorting to conjunction's e.g.
Code:
DetachedCriteria productCriteria = DetachedCriteria
    .forClass(Product.class)
    .createAlias("productMetaData", "pmd");
Conjunction conjunction = Restrictions.conjunction();
conjunction.add(Restrictions.eq("pmd.metaData", metaData1));
conjunction.add(Restrictions.eq("pmd.metaData", metaData2));
productCriteria.add(conjunction);


But I dont seem to be able to create the appropriate alias'. Heres the Hibernate generated code (probably doesnt match the example above as my code keeps changing, but they all seem to have the same problem of only having a single alias.

Code:
select this_.product_id as product1_3_ from product this_ inner join product_validation_data productval1_ on this_.product_id=productval1_.product_fk inner join metadata metadata2_ on productval1_.metadata_fk=metadata2_.metadata_id  where ( (metadata2_.metatag_fk=4 and metadata2_.value='1234567') and (metadata2_.metatag_fk=5 and metadata2_.value='12345'));


I'm sure I'm missing something simple. Anyone got any ideas?

Hibernate Version:3.0.5


Top
 Profile  
 
 Post subject: Re: Writing Criteria for Conjunction in a collection
PostPosted: Fri Jan 27, 2006 2:19 pm 
Newbie

Joined: Thu Jan 26, 2006 6:19 am
Posts: 19
chrish wrote:
Code:
DetachedCriteria productCriteria = DetachedCriteria
    .forClass(Product.class)
    .createAlias("productMetaData", "pmd");
Conjunction conjunction = Restrictions.conjunction();
conjunction.add(Restrictions.eq("pmd.metaData", metaData1));
conjunction.add(Restrictions.eq("pmd.metaData", metaData2));
productCriteria.add(conjunction);



try this one,
Criteria criteria = new Criteria(Product.class)
.createAlias("pvd0", "validations0")
.createAlias("pvd1", "validations1")
.add(Restriction.propertyEq("pvd0.product_fk", "product_id"))
.add(Restriction.propertyEq("pvd1.product_fk", "product_id"))
.add(Restriction.eq("pvd0.metadata_fk","4"))
.add(Restriction.eq("pvd1.metadata_fk","5"));
criteria.list();

Conjuctions means "OR" in sql, you dont need it in your case..


Top
 Profile  
 
 Post subject:
PostPosted: Sat Jan 28, 2006 6:54 am 
Newbie

Joined: Fri Apr 08, 2005 6:26 am
Posts: 6
Location: Edinburgh, UK
Thanks, this has helped a little.
I was missing the restriction on the product_id, but I'm unsure about the way in which you use the createAlias though.
If Product has the collection Product.validationMetaData, I would have expected it to be as follows (also translated your example to my object domain):

Code:
DetachedCriteria productCriteria = DetachedCriteria.forClass(Product.class)
  .createAlias("validationMetaData", "validate0")
  .add(Restriction.propertyEq("validate0.product", "product"))
  .add(Restriction.eq("validate0.metaData",metaDataObject4))

  .createAlias("validationMetaData", "validate1")
  .add(Restriction.propertyEq("validate1.product", "product"))
  .add(Restriction.eq("validate1.metaData",metaDataObject5));


Although my original example doesnt show it, I have tried using createAlias like this before, but I get the following exception:

Code:
org.springframework.orm.hibernate3.HibernateQueryException: duplicate association path: validationMetaData; nested exception is org.hibernate.QueryException: duplicate association path: validationMetaData
org.springframework.orm.hibernate3.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:652)
org.springframework.orm.hibernate3.HibernateAccessor.convertHibernateAccessException(HibernateAccessor.java:413)
org.springframework.orm.hibernate3.HibernateTemplate.execute(HibernateTemplate.java:370)
org.springframework.orm.hibernate3.HibernateTemplate.findByCriteria(HibernateTemplate.java:951)
...


Am I to understand from this that you cannot do multiple aliases for a property? Or have I missed something again?

TIA
Chris

btw:
Quote:
onur wrote:
Conjuctions means "OR" in sql, you dont need it in your case..

Disjunction is "OR", Conjunction is "AND"


Top
 Profile  
 
 Post subject:
PostPosted: Sat Jan 28, 2006 7:46 am 
Newbie

Joined: Fri Apr 08, 2005 6:26 am
Posts: 6
Location: Edinburgh, UK
Due to looming deadlines, I have implemented this in HQL.

Would still be interested to find out the Criteria methodology though.

Regards,
Chris


Top
 Profile  
 
 Post subject:
PostPosted: Mon Feb 13, 2006 12:55 pm 
Newbie

Joined: Thu Jan 26, 2006 6:19 am
Posts: 19
Well what you're trying to do is illegal for hibernate:)

for creating two sub criterias you should have to collections.
That is to say, you should link validationMetaDatas in Product hbm file.

so you can use something like:
.createAlias("validationMetaData0", "validate0")
.createAlias("validationMetaData1", "validate1")

Dont forget to rate:)

chrish wrote:
Thanks, this has helped a little.
I was missing the restriction on the product_id, but I'm unsure about the way in which you use the createAlias though.
If Product has the collection Product.validationMetaData, I would have expected it to be as follows (also translated your example to my object domain):

Code:
DetachedCriteria productCriteria = DetachedCriteria.forClass(Product.class)
  .createAlias("validationMetaData", "validate0")
  .add(Restriction.propertyEq("validate0.product", "product"))
  .add(Restriction.eq("validate0.metaData",metaDataObject4))

  .createAlias("validationMetaData", "validate1")
  .add(Restriction.propertyEq("validate1.product", "product"))
  .add(Restriction.eq("validate1.metaData",metaDataObject5));


Although my original example doesnt show it, I have tried using createAlias like this before, but I get the following exception:

Code:
org.springframework.orm.hibernate3.HibernateQueryException: duplicate association path: validationMetaData; nested exception is org.hibernate.QueryException: duplicate association path: validationMetaData
org.springframework.orm.hibernate3.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:652)
org.springframework.orm.hibernate3.HibernateAccessor.convertHibernateAccessException(HibernateAccessor.java:413)
org.springframework.orm.hibernate3.HibernateTemplate.execute(HibernateTemplate.java:370)
org.springframework.orm.hibernate3.HibernateTemplate.findByCriteria(HibernateTemplate.java:951)
...


Am I to understand from this that you cannot do multiple aliases for a property? Or have I missed something again?

TIA
Chris

btw:
Quote:
onur wrote:
Conjuctions means "OR" in sql, you dont need it in your case..

Disjunction is "OR", Conjunction is "AND"


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 5 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.