2013-01-04 29 views
3

我正在使用hibernate 4.1.5.Final和Spring 3.1.2 Release和Jboss 7.1。我已經使用@NamedQuery註解在類中編寫了所有命名查詢,但實體管理器未創建命名查詢。我張貼的堆棧跟蹤和context.xml的java.lang.IllegalArgumentException:未找到命名查詢(實體管理器未創建NamedQuery)

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

此鏈接可能對您有幫助 - http:// stackoverflow.com/questions/6170527/namedquery-illegalargumentexception-query-not-found-after-externalizing-entit –

+0

是的,我已經看到這個..我已經添加到實體管理器bean,它將掃描所有的實體類。 –

+0

試試這個 - http://forum.springsource.org/showthread.php?108914-Spring-Hibernate-JPA-java-lang-IllegalArgumentException-命名查詢未找到 –

回答

4
I have written all named queries in a class with @NamedQuery annotation 

您沒有明確提及類的,你是在上述發言中提及的類型?您需要在Entity類(使用@Entity註解進行註釋的類)中編寫命名查詢。

更新: 我現在有點困惑你的班級DBNamedQuery。你說你正在使用一個類來放置所有命名查詢。我的理解是你正在使用這個類爲你的應用程序的所有實體編寫命名查詢。如果這是正確的,你怎麼能在你的課DBNamedQuery上使用@Entity註釋,因爲它不是一個真正的jpa實體?

包含@NamedQuery註釋的類應該是一個託管實體。我懷疑你的班級DBNamedQuery不是。

要確定問題,我建議檢查日誌,如果這是一個被管理的實體。如果你不能這樣做EntityManger給你和API檢查,在運行時contains(java.lang.Object entity)

在相關說明中,如果您使用註釋,那麼JPA命名查詢是jpa實體的一部分。使用xml可讓您靈活地存儲在單獨的文件中。

+0

我已經更新了課堂上你問的問題。 –

+0

是的,我的DBNamedQuery是一個jpa實體,我用它來爲所有實體單獨編寫所有的查詢。 org.hibernate.ejb3persistence是我的持久性提供者。錯誤意味着我的持久性單元未正確註冊? –

+0

@Kabilan:我不會說持久性單元已經正確註冊。這個錯誤意味着你的命名查詢不應該出現在它應該是的地方,因爲它僅在實體中查找命名查詢,或者在持久性單元中註冊xml。您可以將您的命名查詢移動到相應的實體或單獨的xml,並在persistence.xml中定義該xml,以便持久性單元知道它。 – Parvez

1

檢查您的實體類DBNamedQuery是在包com.project.entities如您在的applicationContext.xml文件

+0

它是一個適當的實體文件。我已經把它放在db包中,我也在使用它的組件掃描 –

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文件中的資源文件夾,並在您的applicationContext企業-config.xml文件中寫如下

<property name="mappingResources"> 
    <list> 
     <value>/resources/hbms/Queries.hbm.xml</value> 
    </list> 
</property> 

所以它會正常工作。

編輯 那麼這取決於你如何在你的DAO層調用它。你必須調用像=>

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表示參數的值。

+0

我試過你的建議和它的工作 –

+0

看到我編輯了答案你必須這樣做,你必須做的applicationContext-enterprise-config web.xml中的.xml文件也是 – Prafulla

1

我認爲這是因爲名字遺漏匹配。 在@NamedQuery中聲明的名稱與名爲該查詢的名稱不匹配。

@NamedQuery(name = "AAAA", query = ...) //must be same the name which call that query 

public void some() { 
    Query q = em.createNamedQuery("AAAA"); 
} 
+0

名稱是正確的。持久單元提供程序是org.hibernate.ejb.HibernatePersistence以及如何檢查我的持久性提供程序是否已正確註冊? –

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; 
     } 
相關問題