Spring Boot 3 Data JPA EntityManagerFactory 在单元测试中找不到。

huangapple go评论103阅读模式
英文:

Spring Boot 3 Data JPA EntityManagerFactory can't be found in Unit Test

问题

有一个旧的Spring应用程序,后来我将其转换为Spring Boot,仍然保留了许多仍然有效的遗留XML文件。我决定将这个项目存档到GitHub,并创建一个全新的、非常正常的Spring Boot 3应用程序,其中包含Spring Data JPA。

我使用Spring Starter初始化器创建了这个应用程序,确实,我包含了Spring Data JPA。最终的想法是将其放入Docker容器作为微服务,并部署到我的Amazon ECR服务。

我一直在按照Spring Data JPA的文档进行操作,我认为问题主要在于我的单元测试。问题是单元测试无法找到我的DAO或Repository。所以,让我从目前为止的文件开始添加:

application.properties:

spring.datasource.url=jdbc:mysql://localhost:3306/library_db?serverTimezone=UTC
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.username=user
spring.datasource.password=
spring.jpa.show-sql=true
@SpringBootApplication
public class LibraryApplication  {
    public static void main(String[] args) {
        SpringApplication.run(LibraryApplication.class, args);
    }
}
@Configuration
@EnableAutoConfiguration
@ComponentScan("com.tomholmes.products.library")
@EntityScan("com.tomholmes.products.library.model")
@EnableJpaRepositories(basePackages = "com.tomholmes.products.library.repository")
@EnableTransactionManagement
public class DatabaseConfiguration  {
}
public interface BookDao extends JpaRepository<BookEntity, Long> {
}
@Transactional
@SpringBootTest(classes = { LibraryApplication.class, DatabaseConfiguration.class })
public class BookDaoTest  {
    @Autowired
    private BookDao bookDao;

    @Test
    public void testFindById() {
        long bookId = 2;
        BookEntity book = bookDao.findById(bookId).orElse(null);
        assertNotNull(book);
        assertEquals(bookId, book.getBookId());
    }
}

这个测试和其他类似的测试是为了确保Spring Boot 3与Spring Data JPA中的基本数据库配置正确配置。我认为我遇到的问题最终在于测试本身。我今天看到的大多数其他StackOverflow帖子和其他帖子仍然集中在Spring Boot 2上,而不是3,尽管它们应该非常相似。

我在单元测试中遇到的问题是这个错误消息:

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'entityManagerFactory' available

从我今天的所有研究中,entityManagerFactory在JPARepository中被定义,所以不应该需要特别定义。我只是不知道为什么会出现这个错误。

我知道我没有添加pom.xml或实体代码本身,但如果你需要的话,我可以提供它们。

英文:

I had an old Spring Application for a personal project and I converted it to Spring Boot later and still kept a lot of legacy XML files which worked. I decided to archive this project on GitHub and create a very NEW very normal Spring Boot 3 application with Spring Data JPA.
I created this application with the Spring Starter initializer as one does, and yep, I did include Spring Data JPA. The idea eventually is to put this in a Docker Container as a Microservice and deploy to my Amazon ECR Service.

I have been following the documentation for Spring Data JPA, and I think the problem is strictly in my unit test. The problem is that the unit test cannot find my DAO or Repository. So, let me start by adding the files that I have so far:

application.properties:

spring.datasource.url=jdbc:mysql://localhost:3306/library_db?serverTimezone=UTC
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.username=user
spring.datasource.password=
spring.jpa.show-sql=true

@SpringBootApplication
public class LibraryApplication  {
    public static void main(String[] args) {
        SpringApplication.run(LibraryApplication.class, args);
    }
}

@Configuration
@EnableAutoConfiguration
@ComponentScan(&quot;com.tomholmes.products.library&quot;)
@EntityScan(&quot;com.tomholmes.products.library.model&quot;)
@EnableJpaRepositories(basePackages = &quot;com.tomholmes.products.library.repository&quot;)
@EnableTransactionManagement
public class DatabaseConfiguration  {
}

public interface BookDao extends JpaRepository&lt;BookEntity, Long&gt; {
}

@Transactional
@SpringBootTest(classes = { LibraryApplication.class, DatabaseConfiguration.class })
public class BookDaoTest  {
    @Autowired
    private BookDao bookDao;

    @Test
    public void testFindById() {
        long bookId = 2;
        BookEntity book = bookDao.findById(bookId).orElse(null);
        assertNotNull(book);
        assertEquals(bookId, book.getBookId());
    }
}

This test and others like it is to ensure that the basic database configuration in Spring Boot 3 with Spring Data JPA is configured correctly. I think the problem I am having ultimately is in the test itself. Most of the other StackOverflow posts I have seen and others are still focused on Spring Boot 2 and not 3, even though they should be very similar.

The problem I am having in my unit test is this error message:

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: 
No bean named &#39;entityManagerFactory&#39; available

From all the research I did today, the entityManagerFactory is defined in the JPARepository, so it shouldn't have to be specifically defined. I just don't know why this error is even coming up.

I know I didn't add the pom.xml or the entity code itself, but if you need those I can provide them.

答案1

得分: 0

以下是已经翻译好的部分:

所以,我通过一些尝试和错误找到了答案,但Semyon的回应给了我一些更多的方向。

所以,pom.xml 最初是这样的:

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<exclusions>
<exclusion>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
</exclusion>
</exclusions>
</dependency>

我将它更改为:

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

这解决了entityManagerFactory的问题,问题已经解决。我还将测试标头更改为:

@DataJpaTest
@AutoConfigureTestDatabase(replace =
AutoConfigureTestDatabase.Replace.NONE)
public class BookDaoTest {

@DataJpaTest 注释正好做了我需要做的事情,也就是将数据库视为集成测试。是的,我们确实插入、更新和删除,但这个注释在每次测试结束时都会回滚,这正是我们想要的。

由于我正在使用本地运行在我的笔记本电脑上的真实MySQL数据库,所以我不得不添加注释:
@AutoConfigureTestDatabase
而参数:
replace = AutoConfigureTestDatabase.Replace.NONE
意味着不要用嵌入式数据库替换数据库。

我认为这将解决我的问题。

英文:

So, I found answer with some more trial and error, but the response from Semyon gave me some more direction.

So, the pom.xml has this originally:

     &lt;dependency&gt;
		&lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
		&lt;artifactId&gt;spring-boot-starter-data-jpa&lt;/artifactId&gt;
		&lt;exclusions&gt;
			&lt;exclusion&gt;
				&lt;groupId&gt;com.zaxxer&lt;/groupId&gt;
				&lt;artifactId&gt;HikariCP&lt;/artifactId&gt;
			&lt;/exclusion&gt;
		&lt;/exclusions&gt;
	&lt;/dependency&gt;

and I changed it to just:

&lt;dependency&gt;
		&lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
		&lt;artifactId&gt;spring-boot-starter-data-jpa&lt;/artifactId&gt; 
&lt;/dependency&gt;

and this solved the problem with the entityManagerFactory issue, that got resolved. I also changed the test header to:

@DataJpaTest
@AutoConfigureTestDatabase(replace =
AutoConfigureTestDatabase.Replace.NONE)
public class BookDaoTest {

The @DataJpaTest annotation does exactly what I needed to do, which is just test the database as an integration test. Yes, we really insert, update, and delete, but this annotation rolls back at the end of every test which is what we want.

Since I am using a real MySQL database running locally on my laptop, then I had to add the annotation:
@AutoConfigureTestDatabase
and it seems the parameter:
replace = AutoConfigureTestDatabase.Replace.NONE
means to not replace the database with an embedded database.

I think this is going to solve the issues for me.

huangapple
  • 本文由 发表于 2023年3月12日 07:21:21
  • 转载请务必保留本文链接:https://go.coder-hub.com/75710178.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定