Jpa Query.setParameter如何与MetaValue(多态查询)一起使用?

时间:2010-02-22 21:39:27

标签: hibernate jpa

我一直在尝试在以下域方案中使用JPA(hibernate作为提供者)的多态查询:

PriceTable(1)< --->(n)ItemPrice(n)< ----> (1)项目

因此,对于在我的系统中注册的每个PriceTable,我有一组项目价格,用于描述该表格中给定项目的价格。项目可以是设备或结构,我打算增加层次结构。

类声明如下(plz假设id正在工作):

@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 {
  //...
}

当我尝试使用Query.setParameter查询其priceList中包含给定Item的所有PriceTable时,对于我感兴趣的Item类,它总是将参数绑定为null。看一下查询代码:

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'");

跟踪休眠给了我这个:

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

当然,根本不给我任何价值。奇怪的是,如果我手动设置matevalued参数,例如:

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());

完美无缺。所以我认为hibernate / JPA不会将查询参数解析为它应该的元值(看看hibernate documentation about this)。可能它被解析为一个字符串。你们有解决方法吗?我真的不想在我的代码上使用开关来克服这个setParameter奇怪的行为。

非常感谢!

1 个答案:

答案 0 :(得分:2)

尝试从文字中删除单引号:

q.setParameter(2, "Equipment");

而不是

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

如果这不起作用,请尝试使用完全限定的类名。