在JBoss AS 7.1.1上,为什么Hibernate的AnnotationBinder没有检测到带注释的实体?

时间:2013-06-10 08:12:17

标签: spring hibernate java-ee migration jboss7.x

我正在尝试将Spring应用程序从JBoss AS 4.0.5.GA迁移到7.1.1.Final。在我的jboss-spring.xml中有一个bean engine,其init方法导致下面的createQuery行被执行。

public class QueueConfigurationDAO {
    private EntityManager _entityManager;

    @PersistenceContext
    public void setEntityManager(EntityManager entityManager) {
        _entityManager = entityManager;
    }

    public List<QueueConfiguration> getQueueConfigurations() {
        Query query = _entityManager.createQuery("from QueueConfiguration");
        return query.getResultList();
    }
}

这导致以下堆栈跟踪:

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'engine' defined in "/C:/Users/Emil/JBoss/jboss-as-7.1.1.Final/standal
one/deployments/zz10-wf.spring/META-INF/jboss-spring.xml": Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: org.hibernate.hql.i
nternal.ast.QuerySyntaxException: QueueConfiguration is not mapped [from QueueConfiguration]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1488)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:524)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:461)
        at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:295)
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:292)
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:626)
        at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:932)
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:479)
        at org.jboss.spring.factory.NamedXmlApplicationContext.<init>(NamedXmlApplicationContext.java:69)
        at org.jboss.spring.factory.NamedXmlApplicationContext.<init>(NamedXmlApplicationContext.java:59)
        at org.jboss.spring.deployers.as7.SpringBootstrapProcessor.deploy(SpringBootstrapProcessor.java:69)
        at org.jboss.as.server.deployment.DeploymentUnitPhaseService.start(DeploymentUnitPhaseService.java:113) [jboss-as-server-7.1.1.Final.jar:7.1.1.Final]
        ... 5 more
Caused by: java.lang.IllegalArgumentException: org.hibernate.hql.internal.ast.QuerySyntaxException: QueueConfiguration is not mapped [from QueueConfiguration]
        at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1348)
        at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1289)
        at org.hibernate.ejb.AbstractEntityManagerImpl.createQuery(AbstractEntityManagerImpl.java:288)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) [rt.jar:1.7.0_02]
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) [rt.jar:1.7.0_02]
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) [rt.jar:1.7.0_02]
        at java.lang.reflect.Method.invoke(Method.java:601) [rt.jar:1.7.0_02]
        at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:241)
        at $Proxy118.createQuery(Unknown Source)        at se.sunstone.workflow.queues.QueueConfigurationDAO.getQueueConfigurations(QueueConfigurationDAO.java:28)
        at se.sunstone.workflow.queues.StandardQueueManager.configure(StandardQueueManager.java:71)
        at se.sunstone.workflow.queues.StandardQueueManager.start(StandardQueueManager.java:52)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) [rt.jar:1.7.0_02]
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) [rt.jar:1.7.0_02]
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) [rt.jar:1.7.0_02]
        at java.lang.reflect.Method.invoke(Method.java:601) [rt.jar:1.7.0_02]
        at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
        at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:96)
        at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:260)
        at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:94)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
        at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
        at $Proxy121.start(Unknown Source)      at se.sunstone.workflow.engine.ExecutionEngine.start(ExecutionEngine.java:177)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) [rt.jar:1.7.0_02]
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) [rt.jar:1.7.0_02]
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) [rt.jar:1.7.0_02]
        at java.lang.reflect.Method.invoke(Method.java:601) [rt.jar:1.7.0_02]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeCustomInitMethod(AbstractAutowireCapableBeanFactory.java:1614)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1555)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1485)
        ... 18 more
Caused by: org.hibernate.hql.internal.ast.QuerySyntaxException: QueueConfiguration is not mapped [from QueueConfiguration]
        at org.hibernate.hql.internal.ast.util.SessionFactoryHelper.requireClassPersister(SessionFactoryHelper.java:180)
        at org.hibernate.hql.internal.ast.tree.FromElementFactory.addFromElement(FromElementFactory.java:110)
        at org.hibernate.hql.internal.ast.tree.FromClause.addFromElement(FromClause.java:93)
        at org.hibernate.hql.internal.ast.HqlSqlWalker.createFromElement(HqlSqlWalker.java:326)
        at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.fromElement(HqlSqlBaseWalker.java:3252)
        at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.fromElementList(HqlSqlBaseWalker.java:3141)
        at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.fromClause(HqlSqlBaseWalker.java:694)
        at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.query(HqlSqlBaseWalker.java:550)
        at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.selectStatement(HqlSqlBaseWalker.java:287)
        at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.statement(HqlSqlBaseWalker.java:235)
        at org.hibernate.hql.internal.ast.QueryTranslatorImpl.analyze(QueryTranslatorImpl.java:248)
        at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:183)
        at org.hibernate.hql.internal.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:136)
        at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:101)
        at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:80)
        at org.hibernate.engine.query.spi.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:119)
        at org.hibernate.internal.AbstractSessionImpl.getHQLQueryPlan(AbstractSessionImpl.java:214)
        at org.hibernate.internal.AbstractSessionImpl.createQuery(AbstractSessionImpl.java:192)
        at org.hibernate.internal.SessionImpl.createQuery(SessionImpl.java:1537)
        at org.hibernate.ejb.AbstractEntityManagerImpl.createQuery(AbstractEntityManagerImpl.java:285)
        ... 48 more

我认为QuerySyntaxException: QueueConfiguration is not mapped意味着我的

@javax.persistence.Entity
@javax.persistence.Table(name = "queue_configuration")
public class QueueConfiguration { /* ... */ }

类不被Hibernate识别为实体。实际上,当我在JBoss 4中运行应用程序时,启动日志包含像

这样的行
INFO  [org.hibernate.cfg.AnnotationBinder] Binding entity from annotated class: se.sunstone.workflow.queues.QueueConfiguration

但是当我尝试在JBoss 7中部署它时,日志中不会出现这样的行。如果我从engine注释掉jboss-spring.xml bean,那么应用程序会愉快地部署而没有例外。

我正在使用JBoss 7的内置Hibernate模块,而我正在使用Snowdrop模块部署我的webapp。我已经花了好几天了,包括尝试使用Hibernate 3,但问题仍然存在。

如果我在<class>se.sunstone.workflow.queues.QueueConfiguration</class>中明确指定persistence.xml,则应用程序将部署并且日志现在包含与在JBoss 4上运行时相同的AnnotationBinder行。但是,该应用程序还有一堆其他带注释的实体,其DAO在下面的配置中被省略,除非我在persistence.xml中指定它们,否则不会检测到它们。显然,AnnotationBinder不检测带注释的实体,除非我在persistence.xml中指定它们。那是为什么?

详细

档案布局:

zz10-wf.spring
-- META-INF
---- jboss-deployment-structure.xml
---- jboss-spring.xml
---- jpa-persistence.xml
---- MANIFEST-MF
-- (Java package hierarchy)

关注these instructions我已将传统的persistence.xml重命名为jpa-persistence.xml,以便JBoss不会检测到它并启动自己的Hibernate实例。

zz10-wf.spring目前已部署为展开目录,但如果我将其部署为未压缩的zip存档,则会发生同样的情况。

jboss-deployment-structure.xml

<jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.0">
    <deployment>
        <exclusions>
            <module name="org.hibernate"/>
        </exclusions>
    </deployment>
</jboss-deployment-structure>

jboss-spring.xml

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:jee="http://www.springframework.org/schema/jee"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                             http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
                           http://www.springframework.org/schema/jee
                             http://www.springframework.org/schema/jee/spring-jee-2.0.xsd
                           http://www.springframework.org/schema/tx
                             http://www.springframework.org/schema/tx/spring-tx.xsd">

  <!-- =========  Central application configuration  ========= -->
  <bean id="queueManager" class="se.sunstone.workflow.queues.StandardQueueManager"> 
    <property name="queueConfigurationDAO" ref="queueConfigurationDAO"/>
  </bean>

  <bean id="engine" class="se.sunstone.workflow.engine.ExecutionEngine" init-method="start" destroy-method="stop">  
    <property name="queueManager" ref="queueManager"/>
  </bean>

  <!-- =========  DAOs  ========= -->
  <bean id="queueConfigurationDAO" class="se.sunstone.workflow.queues.QueueConfigurationDAO" /> 

  <!-- =========  JPA  ========= -->
  <bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />

  <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="persistenceXmlLocation" value="classpath*:META-INF/jpa-persistence.xml"/>
    <property name="dataSource" ref="dataSource"/>
    <property name="persistenceUnitName" value="workflow" />
    <property name="jpaVendorAdapter">
      <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
        <property name="showSql" value="false" />
        <property name="generateDdl" value="true" />
        <property name="databasePlatform" value="org.hibernate.dialect.PostgreSQLDialect"/>
      </bean>
    </property>
  </bean>

  <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="entityManagerFactory" ref="entityManagerFactory" />
  </bean>

  <tx:annotation-driven />

  <jee:jndi-lookup id="dataSource" jndi-name="java:jboss/WorkflowDS"/>

</beans>

jpa-persistence.xml

<persistence xmlns="http://java.sun.com/xml/ns/persistence"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
                                   http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
             version="1.0">
  <persistence-unit name="workflow">
      <!-- <class>se.sunstone.workflow.queues.QueueConfiguration</class> -->
  </persistence-unit>
</persistence>

我尝试在jpa-persistence.xmlentityManagerFactory bean定义之间来回移动配置详细信息,结果大致相同,并且应用程序同意使用此最小jpa-persistence.xml运行因为上面的QueueConfiguration行已取消注释。

2 个答案:

答案 0 :(得分:1)

在这个问题的earlier incarnation中,我的一个问题是AnnotationBinder运行两次的原因。我认为这是因为JBoss检测到persistence.xml并且与Spring发起的实例并行启动了自己的Hibernate实例。在将persistence.xml重命名为jpa-persistence.xml(任何其他名称可能会执行此操作)之后,如in the JBoss AS 7 documentation所述,此行为已停止。但是,AnnotationBinder未检测到带注释的实体的问题仍然存在。

我从问题中编辑了这些问题,因为我希望问题更具体地说明为什么AnnotationBinder没有检测到带注释的实体。

答案 1 :(得分:0)

请更新&#34; entityManagerFactory&#34; jboss-spring.xml中的bean如下:

  • 删除&#34; persistenceXmlLocation&#34;属性
  • 添加&#34; packagesToScan&#34;财产如下:

示例(替换&#34; your_jpa_related_base_package&#34;与实际的一样):

<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<!--
<property name="persistenceXmlLocation" value="classpath*:META-INF/jpa-persistence.xml"/>
-->
<property name="dataSource" ref="dataSource"/>
<property name="packagesToScan" value="your_jpa_related_base_package" />
<property name="persistenceUnitName" value="workflow" />

<property name="jpaVendorAdapter">
  <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
    <property name="showSql" value="false" />
    <property name="generateDdl" value="true" />
    <property name="databasePlatform" value="org.hibernate.dialect.PostgreSQLDialect"/>
  </bean>
</property>