当前位置: 首页 > 知识库问答 >
问题:

Spring启动 JPA 注入实体管理器没有实体管理器可用

骆雅昶
2023-03-14

我试图使用spring boot将EntityManager注释注入到我的DAO中,但是得到一个< code > InvalidDataAccessApiUsageException 消息,说没有可用的事务EntityManager。我的印象是,只要Spring Boot从< code>application.yml中获得了我的数据源信息,并且我用< code>@PersitenceContext标记了我的DAO中的< code>EntityManager字段,它就会基本上为我处理所有的事情,所以我不需要在自己的代码中使用EntityManagerFactory,也不需要< code>persistence.xml文件。我错了吗?

我的DAO:

@Repository
public class PersonDaoJpa implements PersonDao {

    @PersistenceContext
    private EntityManager em;

    ...

    DAO methods

    ...
}

我的Spring Boot配置:

@SpringBootApplication
@EnableTransactionManagement
@ComponentScan(basePackages = {ProgramInfo.BASE_PACKAGE})
@EntityScan(basePackages = {ProgramInfo.BASE_PACKAGE})
public class PersonServiceConfiguration {

    public static void main(String[] args) {

        SpringApplication.run(PersonServiceConfiguration.class, args);
    }
}

我的J单位测试:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = PersonServiceConfiguration.class)
@TestExecutionListeners({ DependencyInjectionTestExecutionListener.class,
    DirtiesContextTestExecutionListener.class,
    TransactionalTestExecutionListener.class,
    DbUnitTestExecutionListener.class })
@EnableTransactionManagement
@DatabaseSetup("/test_data_start.xml")
public class PersonDaoJpaTest {

    @Autowired
    private PersonDaoJpa dao;

    ...

    JUnit tests 

    ...
}

我的< code>application.yml文件:

spring:
    profiles.active: default

---

spring:
    profiles: default

spring.datasource:
    driverClassName: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/database?autoReconnect=true
    username: user
    password: pwd

spring.jpa.show-sql: false
spring.jpa.database-platform: org.hibernate.dialect.MySQL5InnoDBDialect

最后是我的< code>pom.xml文件:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.2.2.RELEASE</version>
  </parent>  
  <groupId>myId</groupId>
  <artifactId>myArtifictId</artifactId>
  <version>0.0.1-SNAPSHOT</version>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

  <dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jdbc</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>

    <dependency>
        <groupId>org.dbunit</groupId>
        <artifactId>dbunit</artifactId>
        <version>2.5.1</version>
    </dependency>
    <dependency>
        <groupId>com.github.springtestdbunit</groupId>
        <artifactId>spring-test-dbunit</artifactId>
        <version>1.2.1</version>
    </dependency>
    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-dbcp2</artifactId>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
    </dependency>
  </dependencies>

  <repositories>
      <repository>
          <id>spring-releases</id>
          <url>https://repo.spring.io/libs-release</url>
      </repository>
  </repositories>
  <pluginRepositories>
      <pluginRepository>
          <id>spring-releases</id>
          <url>https://repo.spring.io/libs-release</url>
      </pluginRepository>
  </pluginRepositories>
</project>

这是我得到的完整例外:

org.springframework.dao.InvalidDataAccessApiUsageException: No transactional EntityManager available; nested exception is javax.persistence.TransactionRequiredException: No transactional EntityManager available
at org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.java:410)
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:216)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:417)
at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:59)
at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:213)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:147)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:653)
at com.accenture.javadojo.orgchart.dao.PersonDaoJpa$$EnhancerBySpringCGLIB$$6c935a0d.flush(<generated>)
at dao.PersonDaoJpaTest.testUpdateInvalid(PersonDaoJpaTest.java:92)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:73)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:82)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:73)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:224)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:83)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:68)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:163)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)

Caused by: javax.persistence.TransactionRequiredException: No transactional EntityManager available
at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:275)
at com.sun.proxy.$Proxy54.flush(Unknown Source)
at com.accenture.javadojo.orgchart.dao.PersonDaoJpa.flush(PersonDaoJpa.java:63)
at com.accenture.javadojo.orgchart.dao.PersonDaoJpa$$FastClassBySpringCGLIB$$ed9d6faf.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:717)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136)
... 33 more

更新:当我注释掉< code>dao.flush()时,以下JUnit测试通过:

@Test
public void testFind() {

    Person one = dao.find(1l);
    //dao.flush();
    assertNotNull("User was not found", one);
    assertEquals("Last name not as expected", "one", one.getLastName());
    assertEquals("First name not as expected", "start1", one.getFirstName());
}

但是未注释的情况下,我得到了与上述相同的异常。查找刷新方法如下:

@Override
public Person find(Long id) {

    return em.find(Person.class, id);
}

public void flush() {

    em.flush();
}

共有1个答案

谭仰岳
2023-03-14

您在实现中变得越具体,Spring Boot就越会在它为您所做的事情上退缩。

因为您已经创建了自己的实现,所以现在还需要配置自己的实体管理器,而不是定义实现 CrudRepository 的接口(例如)。

这里有一些留档链接,可以告诉你如何做你需要的:

http://docs.spring.io/spring-boot/docs/current/reference/html/howto-data-access.html

http://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.create-instances.java-config
 类似资料:
  • 我刚刚开始使用Spring ROO,并使用数据库逆向工程命令生成了我的实体类。然而每当我试图调用生成的实体类中的一个CRUD方法时,我总是得到这个异常:Java . lang . illegalstateexception:实体管理器没有被注入(Spring Aspects JAR是否被配置为AJC/AJDT方面库?) 我怀疑(通过查看生成的文件)EntityManager没有被注入到类中。你能告

  • 我有一个EAR应用程序(要部署在WebLogic12c上),它有一个“持久化”组件。“persist”组件使用JPA(实现:EclipseLink)来持久化对象。 使用entityManager的bean声明为,实体管理器通过注释注入。 问题是,我每次尝试访问entityManager时都有一个(意思是他没有被正确注入)。 persistence.xml 我在常规代码中是这样使用的: MyBean

  • 我有一个在Eclipse中定义的非常基本的JavaEE应用程序(一个EJB,一个带有PrimeFaces的网页,一个JPA实体)。它有四个项目,一个用于EAR,一个用于EJB,一个用于JPA,一个用于Web部件。问题是,我试图在JPA项目的persistence.xml中配置HiberNate作为持久化框架,但它并没有像我预期的那样完全工作。在我的EJB(@Statless)中,我可以通过两种方式

  • 问题内容: 一个很长的问题,请忍受我。 我们将Spring + JPA用于Web应用程序。我的团队在讨论如何在注入的(基于泛型的东西对AppFuse中提供的线DAO,我们不使用过的注射某种原因)。我们正在使用“应用程序管理的持久性”。 反对注入a的论点是它太重了,因此不是必需的,这就是我们需要的。而且,由于Spring将为每个Web请求创建一个DAO的新实例(我对此表示怀疑),因此不会有任何并发​

  • 编辑:堆栈跟踪如下: 下面是persistence.xml:

  • 目前,我学习JavaEE JPA规范。我使用Hibernate作为JPA实现。我有下一个问题: 我有一个简单的实体 还有一个简单的服务: persistence.xml有下一个视图: 我不明白为什么Hibernate会话没有注入BookService。在作为EntityManager的图书服务中,我得到了org.jboss.as.TransactionScopedEntityManager而不是来