Scott Turley
Scott Turley

Reputation: 319

Moving Spring Accessing Data with JPA getting started guide to something more complex

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.

Upvotes: 1

Views: 770

Answers (2)

chendu
chendu

Reputation: 584

I'm also confused with this problem. And I have found something on the spring.io site. It's described as @manish, share with you.

By default, Spring Boot will enable JPA repository support and look in the package (and its subpackages) where @SpringBootApplication is located. If your configuration has JPA repository interface definitions located in a package not visible, you can point out alternate packages using @EnableJpaRepositories and its type-safe basePackageClasses=MyRepository.class parameter.

https://spring.io/guides/gs/accessing-data-jpa/

Upvotes: 1

manish
manish

Reputation: 20135

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.

Upvotes: 3

Related Questions