tags:

views:

309

answers:

1

Hi, I've been trying to use polymorphic query with JPA (hibernate as provider) in the following domain scenario:

PriceTable (1) <--->(n) ItemPrice (n) <----> (1) Item

So for each PriceTable registered in my system I have a set of item prices which describe the price of a given item on that table. An item can be an Equipment or a Structure and I intend to increase the hierarchy.

The class declarations are as follows (plz assume that the ids are working):

@Entity
class PriceTable {
 private Set<ItemPrice> priceList = new HashSet<ItemPrice>();
 //getters & setters;
}


@Entity
class ItemPrice {
 private Item item;

    @Any(metaColumn = @Column(name = "itemtype"), fetch = FetchType.LAZY)
     @AnyMetaDef(idType = "long", 
            metaType = "string", 
            metaValues = {
             @MetaValue(value = "Equipment", targetEntity = Equipment.class),
             @MetaValue(value = "Structure", targetEntity = Structure.class)
            })
    @JoinColumn(name="itemid")
    public Item getItem(){ 
      return item; 
    }
}

@MappedSuperClass
class Item {
  //...
}

@Entity
class Equipment extends Item {
  //...
}

@Entity
class Structure extends Item {
  //...
}

When I attempt to query all the PriceTables that contain a given Item in its priceList using Query.setParameter for the kind of Item I'm interested in, it allways binds the parameter as null. Take a look at the query code:

String query = "from PriceTable pt "+ 
               "    where ? in " +
               "    (select ptpricelist.item.id from pt.priceList ptpricelist " +
               "       where ptpricelist.item.class = ?) ";

Query q = entityManager.createQuery(query);
q.setParameter(1, myItem.getId());
q.setParameter(2, "'Equipment'");

The trace hibernate gives me this:

2010-02-22 17:55:32,683 DEBUG [org.hibernate.type.NullableType:126] - binding null to parameter: 2

And of course doesn't give me any value at all. The strange thing is if I set manually the matevalued parameter, like:

String query = "from PriceTable pt "+ 
               "    where ? in " +
               "    (select ptpricelist.item.id from pt.priceList ptpricelist " +
               "       where ptpricelist.item.class = 'Equipment') ";

Query q = entityManager.createQuery(query);
q.setParameter(1, myItem.getId());

It works perfectly. So I think hibernate/JPA doesn't resolve the query parameter as a metavalue as it should (take a look at the hibernate documentation about this). Probably it was resolved as a string. Do you guys have any workaround this? I really don't want to use switchs on my code just to overcome this setParameter strange behaviour.

thanks a lot!

+1  A: 

Try dropping the single quotes from the literal:

q.setParameter(2, "Equipment");

instead of

q.setParameter(2, "'Equipment'"); 

If that doesn't work, try using the fully-qualified class name.

kem
Hi! your second suggestion works flawlessly =). If you try: q.setParameter(2,Equipment.class.getName())hibernate does its magic! thanks a lot mate! really helpful.
Lucas de Oliveira
Glad I could help. Given the model you present, wouldn't a @ManyToOne annotation on getItem() be a lot cleaner? Or have you tried that?
kem
Yes, actually I rewrote the both the relationship (like you suggested) and hql code, it's much simpler now (no subquery needed anymore). Thanks dude!
Lucas de Oliveira