Caused by: org.hibernate.hql.internal.ast.QuerySyntaxException: table is not Mapped问题解决

来源:互联网 发布:慈星股份人工智能 编辑:程序博客网 时间:2024/05/16 18:22

引言: 在基于SpringData/JPA来快速开发若干功能过程中,碰到了table is not Mapped问题,经过一番辛苦的调试测试之后,才发现了一个@Entity的属性name的妙用。

1. 问题的提出

     场景描述: 在开发中,做几个功能类似的模块,但代码需要独立,方便后续的独立部署。故出现了很多包路径不同,但是类的名称类似的类。在Model中定义了很多名称相同的实体类,都是以@Entity来定义的。

@Entity@Table(name="table1")public class Model1 {   ........}
  在项目加载过程中,出席那了以下错误信息:

SEVERE: Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListenerorg.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [META-INF/spring-hibernate.xml]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: myPersistenceUnit] Unable to build EntityManagerFactoryat org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1513)at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:521)at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:458)at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:293)at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:290)at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:191)at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1117)at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:922)at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:479)at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:410)at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:306)at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:112)at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4135)at org.apache.catalina.core.StandardContext.start(StandardContext.java:4630)at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1045)at org.apache.catalina.core.StandardHost.start(StandardHost.java:785)at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1045)at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:445)at org.apache.catalina.startup.Embedded.start(Embedded.java:825)at org.codehaus.mojo.tomcat.AbstractRunMojo.startContainer(AbstractRunMojo.java:558)at org.codehaus.mojo.tomcat.AbstractRunMojo.execute(AbstractRunMojo.java:255)at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:132)at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:208)at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:153)at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:145)at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:116)at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:80)at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build(SingleThreadedBuilder.java:51)at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:120)at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:347)at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:154)at org.apache.maven.cli.MavenCli.execute(MavenCli.java:582)at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:214)at org.apache.maven.cli.MavenCli.main(MavenCli.java:158)at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)at java.lang.reflect.Method.invoke(Method.java:597)at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:289)at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:229)at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:415)at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:356)Caused by: javax.persistence.PersistenceException: [PersistenceUnit: myPersistenceUnit] Unable to build EntityManagerFactoryat org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:924)at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:899)at org.hibernate.ejb.HibernatePersistence.createContainerEntityManagerFactory(HibernatePersistence.java:76)at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:290)at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:310)at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1572)at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1510)... 42 moreCaused by: org.hibernate.AnnotationException: Use of the same entity name twice: OrderEntityat org.hibernate.cfg.annotations.EntityBinder.bindEntity(EntityBinder.java:403)at org.hibernate.cfg.AnnotationBinder.bindClass(AnnotationBinder.java:602)at org.hibernate.cfg.Configuration$MetadataSourceQueue.processAnnotatedClassesQueue(Configuration.java:3568)at org.hibernate.cfg.Configuration$MetadataSourceQueue.processMetadata(Configuration.java:3522)at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1379)at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1784)at org.hibernate.ejb.EntityManagerFactoryImpl.<init>(EntityManagerFactoryImpl.java:96)at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:914)... 48 moreCaused by: org.hibernate.DuplicateMappingException: duplicate import: OrderEntity refers to both com.creditease.bsettle.pay.model.OrderEntity and com.creditease.bsettle.expense.model.OrderEntity (try using auto-import="false")at org.hibernate.cfg.Configuration$MappingsImpl.addImport(Configuration.java:2674)at org.hibernate.cfg.annotations.EntityBinder.bindEntity(EntityBinder.java:396)... 55 more

2. 问题分析

    在项目代码中,的确定义了2个OrderEntity的class,但是他们是处于不同的项目包中的,所以从java类层次上说,是不会冲突的。但是日志中,明确提示了冲突,且标识为重复import,就是说OrderEntity被导入了2次。更进一步说,两个Entity,我们的编译器无法分辨谁是谁,路径区分在这里不好用了。

    经过观察分析,发现在JPA中是利用@Entity来定义标识的, 故推理可知如下信息:

    1.  @Entity标识的实体类是JPA中进行管理和映射的Entity, 其在JPA中默认的名字为class name首字母小写。比如AccountEntity,其默认的实体名称为accountEntity.

   2.   相同的类名在JPA中,默认的实体名称相同,故无法正确识别,这个就是问题的来源。

3.  问题修正

     于是将相同类名的Model类中Entity进行了重新命名,即@Entity(name="entity name"), 确保Entity中的名称不同即可。

4.  遇到新的错误信息

     在修改完毕之后,重新启动系统,然后碰到了新的问题如下:

Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.creditease.bsettle.pay.repository.OrderEntityRepository com.creditease.bsettle.pay.service.impl.OrderServiceImpl.orderEntityRepository; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'orderEntityRepositoryImpl': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: com.creditease.bsettle.pay.repository.OrderEntityRepository com.creditease.bsettle.pay.repository.OrderEntityRepositoryImpl.orderEntityRepository; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'payOrderEntityRepo': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Validation failed for query for method public abstract com.creditease.bsettle.pay.model.OrderEntity com.creditease.bsettle.pay.repository.OrderEntityRepository.findByOuterOrderId(java.lang.String)!at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:517)at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:286)... 54 moreCaused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'orderEntityRepositoryImpl': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: com.creditease.bsettle.pay.repository.OrderEntityRepository com.creditease.bsettle.pay.repository.OrderEntityRepositoryImpl.orderEntityRepository; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'payOrderEntityRepo': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Validation failed for query for method public abstract com.creditease.bsettle.pay.model.OrderEntity com.creditease.bsettle.pay.repository.OrderEntityRepository.findByOuterOrderId(java.lang.String)!at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:289)at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1147)at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519)at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:458)at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:293)at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:290)at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:191)at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:283)at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:191)at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:917)at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:860)at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:775)at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:489)... 56 moreCaused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: com.creditease.bsettle.pay.repository.OrderEntityRepository com.creditease.bsettle.pay.repository.OrderEntityRepositoryImpl.orderEntityRepository; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'payOrderEntityRepo': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Validation failed for query for method public abstract com.creditease.bsettle.pay.model.OrderEntity com.creditease.bsettle.pay.repository.OrderEntityRepository.findByOuterOrderId(java.lang.String)!at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:517)at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:286)... 69 moreCaused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'payOrderEntityRepo': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Validation failed for query for method public abstract com.creditease.bsettle.pay.model.OrderEntity com.creditease.bsettle.pay.repository.OrderEntityRepository.findByOuterOrderId(java.lang.String)!at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1513)at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:521)at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:458)at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:293)at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:290)at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:191)at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:917)at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:860)at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:775)at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:489)... 71 moreCaused by: java.lang.IllegalArgumentException: Validation failed for query for method public abstract com.creditease.bsettle.pay.model.OrderEntity com.creditease.bsettle.pay.repository.OrderEntityRepository.findByOuterOrderId(java.lang.String)!at org.springframework.data.jpa.repository.query.SimpleJpaQuery.validateQuery(SimpleJpaQuery.java:84)at org.springframework.data.jpa.repository.query.SimpleJpaQuery.<init>(SimpleJpaQuery.java:54)at org.springframework.data.jpa.repository.query.JpaQueryFactory.fromMethodWithQueryString(JpaQueryFactory.java:65)at org.springframework.data.jpa.repository.query.JpaQueryFactory.fromQueryAnnotation(JpaQueryFactory.java:48)at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$DeclaredQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:115)at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$CreateIfNotFoundQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:166)at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$AbstractQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:69)at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.<init>(RepositoryFactorySupport.java:320)at org.springframework.data.repository.core.support.RepositoryFactorySupport.getRepository(RepositoryFactorySupport.java:169)at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.initAndReturn(RepositoryFactoryBeanSupport.java:224)at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.afterPropertiesSet(RepositoryFactoryBeanSupport.java:210)at org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean.afterPropertiesSet(JpaRepositoryFactoryBean.java:92)at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1572)at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1510)... 81 moreCaused by: java.lang.IllegalArgumentException: org.hibernate.hql.internal.ast.QuerySyntaxException: OrderEntity is not mapped [from OrderEntity entity where entity.outerOrderId = :outerOrderId]at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1374)at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1310)at org.hibernate.ejb.AbstractEntityManagerImpl.createQuery(AbstractEntityManagerImpl.java:294)at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)at java.lang.reflect.Method.invoke(Method.java:597)at org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.invoke(ExtendedEntityManagerCreator.java:366)at $Proxy48.createQuery(Unknown Source)at org.springframework.data.jpa.repository.query.SimpleJpaQuery.validateQuery(SimpleJpaQuery.java:78)... 94 moreCaused by: org.hibernate.hql.internal.ast.QuerySyntaxException: OrderEntity is not mapped [from OrderEntity entity where entity.outerOrderId = :outerOrderId]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:325)at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.fromElement(HqlSqlBaseWalker.java:3544)at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.fromElementList(HqlSqlBaseWalker.java:3433)at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.fromClause(HqlSqlBaseWalker.java:708)at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.query(HqlSqlBaseWalker.java:564)at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.selectStatement(HqlSqlBaseWalker.java:301)at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.statement(HqlSqlBaseWalker.java:249)at org.hibernate.hql.internal.ast.QueryTranslatorImpl.analyze(QueryTranslatorImpl.java:250)at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:185)at org.hibernate.hql.internal.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:138)at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:104)at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:79)at org.hibernate.engine.query.spi.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:168)at org.hibernate.internal.AbstractSessionImpl.getHQLQueryPlan(AbstractSessionImpl.java:222)at org.hibernate.internal.AbstractSessionImpl.createQuery(AbstractSessionImpl.java:200)at org.hibernate.internal.SessionImpl.createQuery(SessionImpl.java:1703)at org.hibernate.ejb.AbstractEntityManagerImpl.createQuery(AbstractEntityManagerImpl.java:291)... 101 more
5.  问题的二次分析

    这次的错误信息与上次不同,重点是OrderEntity在JQL中无法进行映射,OrderEntity这个类不是已经正确配置到数据库表的映射了吗?那问题出现在哪里呢?

 忽然回想起在之前的@Entity中的实体名已经被重新命名了,不再是缺省的名称了。

     想到这里,就知道问题在哪里了,就是讲JQL中的OrderEntity修改为@Entity(name="xxx")中重新命名的实体名称就可以了。

    重新启动一下系统,错误信息消失了。

6.  @Entity中name作用

     其name所标住的就是实体类的同名信息,可以在JQL中使用。如无特别指定新名称,则默认为类名。

0 0
原创粉丝点击