我正在使用hibernate 4.1.5.Final和Spring 3.1.2 Release以及Jboss 7.1。我已经使用@NamedQuery注释在类中编写了所有命名查询,但实体管理器没有创建命名查询。我发布了stacktrace和context.xml
09:58:49,695 ERROR [stderr] (http-localhost-127.0.0.1-8080-2) java.lang.IllegalArgumentException: Named query not found: validateLoginHash
09:58:49,770 ERROR [stderr] (http-localhost-127.0.0.1-8080-2) at org.hibernate.ejb.AbstractEntityManagerImpl.createNamedQuery(AbstractEntityManagerImpl.java:642)
09:58:49,772 ERROR [stderr] (http-localhost-127.0.0.1-8080-2) at sun.reflect.GeneratedMethodAccessor14.invoke(Unknown Source)
09:58:49,774 ERROR [stderr] (http-localhost-127.0.0.1-8080-2) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
09:58:49,777 ERROR [stderr] (http-localhost-127.0.0.1-8080-2) at java.lang.reflect.Method.invoke(Method.java:597)
09:58:49,779 ERROR [stderr] (http-localhost-127.0.0.1-8080-2) at org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.invoke(ExtendedEntityManagerCreator.java:365)
09:58:49,782 ERROR [stderr] (http-localhost-127.0.0.1-8080-2) at $Proxy30.createNamedQuery(Unknown Source)
09:58:49,784 ERROR [stderr] (http-localhost-127.0.0.1-8080-2) at sun.reflect.GeneratedMethodAccessor14.invoke(Unknown Source)
09:58:49,785 ERROR [stderr] (http-localhost-127.0.0.1-8080-2) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
09:58:49,788 ERROR [stderr] (http-localhost-127.0.0.1-8080-2) at java.lang.reflect.Method.invoke(Method.java:597)
09:58:49,790 ERROR [stderr] (http-localhost-127.0.0.1-8080-2) at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:240)
09:58:49,793 ERROR [stderr] (http-localhost-127.0.0.1-8080-2) at $Proxy30.createNamedQuery(Unknown Source)
的applicationContext.xml
<bean id="jpaDialect" class="org.springframework.orm.jpa.vendor.HibernateJpaDialect"/>
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="jpaDialect" ref="jpaDialect"/>
<property name="packagesToScan" value="com.project.entities"/>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="false" />
<property name="generateDdl" value="false" />
<property name="databasePlatform" value="org.hibernate.dialect.MySQLDialect" />
</bean>
</property>
<!-- <property name="persistenceUnitName" value="Project" /> -->
<property name="persistenceXmlLocation" value="classpath:META-INF/jpa-persistence.xml"/>
<property name="loadTimeWeaver">
<bean
class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver" />
</property>
</bean>
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="java:jboss/datasources/MySqlDS"/>
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
<property name="dataSource" ref="dataSource" />
</bean>
JPA-的persistence.xml
<persistence>
<persistence-unit name="Project" transaction-type="RESOURCE_LOCAL" >
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<non-jta-data-source>java:jboss/datasources/MySqlDS</non-jta-data-source>
<!-- <properties> -->
<!-- <property name="jboss.as.jpa.providerModule" value="hibernate3-bundled" /> -->
<!-- </properties> -->
</persistence-unit>
</persistence>
DBNamedQuery.java
@Entity
@NamedQueries( {
@NamedQuery(name = ... , query = ... ),
@NamedQuery(name = ..., query = ...),
.....More named queries
})
public class DBNamedQuery {
}
答案 0 :(得分:4)
I have written all named queries in a class with @NamedQuery annotation
您没有清楚地提到您在上述声明中提到的班级类型?您需要在Entity类中编写命名查询(使用@Entity注释注释的类)。
更新:
我现在对你的班级DBNamedQuery
感到困惑。您说您正在使用一个类来放置所有命名查询。我的理解是您正在使用此类为应用程序的所有实体编写命名查询。如果这是正确的,您如何在班级@Entity
上使用DBNamedQuery
注释,因为它不是真正的jpa实体?
包含@NamedQuery
注释的类应该是一个托管实体。我怀疑你的班级DBNamedQuery
不是。
要确定问题,我建议检查日志,如果这是一个manged实体。如果您不能这样做,那么EntityManger
会在运行时contains(java.lang.Object entity)
期间为您和API提供检查。
在相关说明中,如果您使用的是注释,那么JPA Named Queries是jpa实体的一部分。使用xml可以灵活地存储在单独的文件中。
答案 1 :(得分:2)
嗨我得到了你的问题,而不是创建一个类为什么不为你的命名查询创建一个xml文件,如Queries.hbm.xml,如下所示
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<!-- Query For User TO -->
<query name="loadUserByUsername">from User u where u.username = ?</query>
</hibernate-mapping>
将此xml文件保存在resources文件夹中,并在applicationContext-enterprise-config.xml文件中将其写入如下
<property name="mappingResources">
<list>
<value>/resources/hbms/Queries.hbm.xml</value>
</list>
</property>
所以它会正常工作。
修改强> 嗯,这取决于你如何在DAO层中调用它。你必须打电话给=&gt;
public int executeNamedQuery(String namedQuery, String namedParams[], Object params[]) throws DatabaseException {
int result = 0;
Session session = getSession();
final String methodName = "executeNamedQuery";
try {
session.beginTransaction();
Query q = session.getNamedQuery(namedQuery);
if (namedParams != null) {
for (int i = 0; i < namedParams.length; i++) {
q.setParameter(namedParams[i], params[i]);
}
}
result = q.executeUpdate();
session.getTransaction().commit();
logger.debug("{} :: {} = {}", new Object[] { methodName, "No. of objects affected", result });
} catch (HibernateException e) {
session.getTransaction().rollback();
final String message = "Couldn't execute the named query " + namedQuery;
logger.error("{} :: {}", new Object[] { methodName, message, e });
throw new DatabaseException(getClass(), methodName, message, e);
} finally {
closeSession();
}
return result;
}
注意:1)namedQuery表示Queries.hbm.xml文件中的查询名称。 2)namedParams []表示Query的参数名称。 3)params表示参数值。
答案 2 :(得分:1)
检查您的实体类DBNamedQuery
是否在 ApplicationContext.xml 文件
com.project.entities
中
答案 3 :(得分:1)
我认为这是因为名字未命中。 在@NamedQuery中声明的名称与调用该查询的名称不匹配。
e.g
@NamedQuery(name = "AAAA", query = ... ) //must be same the name which call that query
public void some() {
Query q = em.createNamedQuery("AAAA");
}
答案 4 :(得分:0)
在persistence.xml中添加注释扫描解决了我的问题
<property name="hibernate.archive.autodetection" value="class, hbm" />
即使我尝试在我的实体管理器中提供包扫描,如下所示 didnt 工作
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(getDataSource());
//em.setPackagesToScan("com.comp.proj.domain");
em.setPersistenceUnitName(PERSISTENCE_UNIT_NAME);
em.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
return em;
}