我正在创建JPQL数据库请求。我有一个超类和两个子类;
@javax.persistence.Entity
@Inheritance( strategy = InheritanceType.JOINED )
public class SuperClass(){
@Column(columnDefinition = "INTEGER")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
// others attributes/getters and setters
}
子类:
@Entity
public class First extends SuperClass{
// attributes, getters and setters
}
@Entity
public class Second extends SuperClass{
// attributes, getters and setters
}
我正在构建一个JPQL查询来获取数据库中的First类结果。我发现一些奇怪的事。我可能会错过一些关于JPQL的东西。
String finalQuery = "SELECT distinct sup from SuperClass sup where sup.class =:myType";
Query query = em.createQuery(finalQuery);
query.setParameter("myType",First);
我在这里得到一个例外:
Caused by: java.lang.IllegalArgumentException: Parameter value [First] was not matching type [java.lang.Integer]
at org.hibernate.ejb.AbstractQueryImpl.registerParameterBinding(AbstractQueryImpl.java:360) ~[hibernate-entitymanager-3.6.8.Final.jar:3.6.8.Final]
at org.hibernate.ejb.QueryImpl.setParameter(QueryImpl.java:364) ~[hibernate-entitymanager-3.6.8.Final.jar:3.6.8.Final]
at org.hibernate.ejb.QueryImpl.setParameter(QueryImpl.java:72) ~[hibernate-entitymanager-3.6.8.Final.jar:3.6.8.Final]
但如果我写
String finalQuery = "SELECT distinct sup from SuperClass sup where sup.class =First";
Query query = em.createQuery(finalQuery);
List<PublishableElement> resultList = query .getResultList();
没有错误。为什么?是不是可以动态传递类类型? 我真的不知道发生了什么。我认为这是其中一条:
Query query = em.createQuery(finalQuery);
query.setParameter("myType",First);
由于
答案 0 :(得分:1)
您已创建了3个类 - SuperClass
,First
,Second
,这些类具有类型InheritanceType.JOINED
的继承策略,因此它们没有任何鉴别器列及其相应的鉴别器值。以下解释仅适用于继承类没有任何鉴别器值来区分类的情况。
现在,当你对这些类执行任何选择查询时,hibernate会做的是检查hibernate配置文件(hibernate.cfg.xml
)并根据实体的顺序为每个类分配一个整数。在配置文件中声明。
例如:
如果hibernate.cfg.xml
文件具有按此顺序声明的实体:
<mapping class="package.SuperClass"/>
<mapping class="package.Second"/>
<mapping class="package.First"/>
然后hibernate将这些数字分配给实体:
SuperClass - 0
Second - 1
First - 2
同样,如果实体声明如下:
<mapping class="package.SuperClass"/>
<mapping class="package.Second"/>
<mapping class="package.First"/>
然后编号
SuperClass - 0
First - 1
Second - 2
String finalQuery = "SELECT distinct sup from SuperClass sup
where sup.class =:myType";
Query query = em.createQuery(finalQuery);
query.setParameter("myType",First);
在此HQL中,您希望根据类类型过滤结果。根据我的上述说明,每个类都分配了一个整数,所以如果你想将它作为参数发送,那么你在query.setParameter()
中传递的参数应该是一个整数。如果你想要然后你需要将整数值传递给0
(假设在hibernate.cfg.xml文件的继承类中首先声明了SuperClass)。
因此,您传递的变量First
必须是整数。
注意:传递一个字符串,例如:“First”到setParameter
将不起作用,因为Hibernate在这种情况下需要一个整数。
String finalQuery = "SELECT distinct sup from SuperClass sup
where sup.class =First";
Query query = em.createQuery(finalQuery);
List<PublishableElement> resultList = query .getResultList();
在这个查询中,你直接告诉你需要类型为First
的类作为String,这个查询是由Hibernate解析的,现在hibernate知道如何将这个字符串First映射到它对应的整数并准备{{ 1}}来自给定SQL select
的查询。
这就是你在第一次HQL查询时获得异常而不是第二次HQL查询的原因。