移动Spring访问数据与JPA入门指导更复杂的事情(Moving Spring Accessing Data with JPA getting started guide to something more complex)

我可以直接从网站上获取在我的机器上运行的示例应用程序: https : //spring.io/guides/gs/accessing-data-jpa/ 。

这个示例应用程序让您开始使用H2嵌入式数据库的简单实现。

它只需要运行两个依赖项:

dependencies { compile("org.springframework.boot:spring-boot-starter-data-jpa") compile("com.h2database:h2") testCompile("junit:junit") }

存储库在此处声明供您参考:

package hello; import java.util.List; import org.springframework.data.repository.CrudRepository; public interface CustomerRepository extends CrudRepository<Customer, Long> { List<Customer> findByLastName(String lastName); }

此存储库已自动装配到配置中。 所有文件都包含在同一个包/目录中。 我假设spring足够聪明,可以实例化实现CustomerRepository的bean的正确实例,该实例提供与h2database的正确连接。 我不确定这是怎么做的,但它确实有效。

代码在这里:

package hello; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class Application implements CommandLineRunner { @Autowired CustomerRepository repository; public static void main(String[] args) { SpringApplication.run(Application.class); } }

它运行时看起来默认情况下,它正在构建一个具有默认hibernate持久性信息的JPA容器,并且运行正常。

但是,当我决定使用此代码作为基线并将CustomerRepository移动到另一个包jpa时,我不再能够将存储库自动装入应用程序。

将@ComponentScan(“jpa”)添加到应用程序没有帮助:

.NoSuchBeanDefinitionException:没有[jpa.CustomerRepository]类型的限定bean

将@EnableJpaRepositories(“jpa”)添加到应用程序会产生不同的错误:

IllegalArgumentException:不是托管类型:class jpa.Customer

因此,只要所有相关类都在同一个包中,看起来我可以使用JPA / Hibernate / H2进行非常简约的配置。

我的问题是,当我想将事物移动到不同的包中时,我是否必须立即转向更复杂的配置,或者是为了保持这种极简主义但仍然能够将事物分开。

I was able to get the sample application running on my machine directly from the website: https://spring.io/guides/gs/accessing-data-jpa/.

This sample application gets you started with a simple implementation of the H2 embedded database.

It requires only two dependencies to run:

dependencies { compile("org.springframework.boot:spring-boot-starter-data-jpa") compile("com.h2database:h2") testCompile("junit:junit") }

The Repository is declared here for your reference:

package hello; import java.util.List; import org.springframework.data.repository.CrudRepository; public interface CustomerRepository extends CrudRepository<Customer, Long> { List<Customer> findByLastName(String lastName); }

This repository is autowired into the configuration. All files are contained in the same package/directory. I'm assuming spring is smart enough to instantiate the correct instance of the bean implementing the CustomerRepository that provides the right connections to the h2database. I'm not sure how that is done here, but it works.

The code is here:

package hello; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class Application implements CommandLineRunner { @Autowired CustomerRepository repository; public static void main(String[] args) { SpringApplication.run(Application.class); } }

When it runs it looks like by default, it's building a JPA container with default hibernate persistence information and it runs fine.

However, when I decide to use this code as a baseline and move the CustomerRepository to another package, jpa, I'm no longer able autowire the repository into the application.

Adding @ComponentScan("jpa") to Application does not help:

.NoSuchBeanDefinitionException: No qualifying bean of type [jpa.CustomerRepository]

Adding @EnableJpaRepositories("jpa") to the Application yields a different error:

IllegalArgumentException: Not an managed type: class jpa.Customer

So, it looks like I can get away with a very minimalistic configuration with JPA/Hibernate/H2 as long as all of the relevant classes are in the same package.

My question is, do I have to immediately need to move toward a more complicated configuration when I want to move things into different packages, or is there to preserve this minimalism but still be able to split things apart.

最满意答案

最简单的方法是将Application类保留在包层次结构的根包中,并将其他类移动到子包中。

org.example | --- Application.java | --- jpa | | | --- CustomerRepository.java | --- model | --- Customer.java

或者,如果您希望子包中的每个类都有自己的类,例如:

org.example | --- bootstrap | | | --- Application.java | --- jpa | | | --- CustomerRepository.java | --- model | --- Customer.java

你还需要使用@EntityScan 。

@SpringBootApplication @EnableJpaRepositories("org.example.jpa") @EntityScan("org.example.model") public class Application ...

有关详细信息,请参阅官方文档

The easiest would be to keep the Application class in the root package of the package hierarchy and move the other classes to sub-packages.

org.example | --- Application.java | --- jpa | | | --- CustomerRepository.java | --- model | --- Customer.java

Alternatively, if you want every class in a sub-package of its own, such as:

org.example | --- bootstrap | | | --- Application.java | --- jpa | | | --- CustomerRepository.java | --- model | --- Customer.java

you will need to use @EntityScan as well.

@SpringBootApplication @EnableJpaRepositories("org.example.jpa") @EntityScan("org.example.model") public class Application ...

See the official documentation for details.

更多推荐