0

When working with Spring Boot and Spring Data JPA, I'm getting null repositories when @Autowiring.

I may have missed some piece of simple configuration, but after hours looking at it and reviewing the docs I find no flaws. I need antoher pair of eyes to take a fresh look.

Here is the relevant configuration:

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

A Service using the repository. When executing doSomething() the repository is null.

@Service
@Slf4j
public class MyService{
  @Autowired
  private MyRepository repository;

  @Override
  public AnEntity doSomething(String index) {
    return repository.findOneByIndex(index);
  }
}

The Repository

public interface MyRepository extends   JpaRepository<AnEntity, String> {
  AnEntity findOneByIndex(String index);
}

The Entity

@Entity
@Table(name = "entities")
@Getter
@Setter
@ToString
public class AnEntity implements Serializable{
  private static final long serialVersionUID = -6256451671609986911L;
  @Id
  @GeneratedValue(strategy=GenerationType.AUTO)
  private Long id;
  private String index;
  private String data;
}

The persistence.xml file

<persistence
    xmlns="http://java.sun.com/xml/ns/persistence"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
    version="2.0">
<persistence-unit name="default">
    <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
    <class>com.myapp.AnEntity</class>
    <properties>
        <property name="hibernate.show_sql" value="true" />
        <property name="javax.persistence.transactionType" value="RESOURCE_LOCAL" />
        <property name="javax.persistence.jdbc.driver" value="org.postgresql.Driver" />
        <property name="javax.persistence.jdbc.url" value="jdbc:postgresql://localhost:5432/authServer" />
        <property name="javax.persistence.jdbc.user" value="user" />
        <property name="javax.persistence.jdbc.password" value="password" />
        <property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect" />
    </properties>
</persistence-unit>

The POM

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xmlns="http://maven.apache.org/POM/4.0.0"
     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>

<groupId>com.myapp</groupId>
<artifactId>myapp</artifactId>
<version>1.0-SNAPSHOT</version>

<packaging>pom</packaging>

<properties>
    <java.version>1.8</java.version>
</properties>

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.2.7.RELEASE</version>
</parent>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.plugin</groupId>
        <artifactId>spring-plugin-core</artifactId>
        <version>1.2.0.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
    <dependency>
        <groupId>org.postgresql</groupId>
        <artifactId>postgresql</artifactId>
        <version>9.4-1201-jdbc41</version>
    </dependency>
    <dependency>
        <groupId>net.logstash.logback</groupId>
        <artifactId>logstash-logback-encoder</artifactId>
        <version>4.5.1</version>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.16.6</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>com.jayway.jsonpath</groupId>
        <artifactId>json-path</artifactId>
        <version>2.0.0</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>br.com.six2six</groupId>
        <artifactId>fixture-factory</artifactId>
        <version>3.0.0</version>
        <exclusions>
            <exclusion>
                <groupId>log4j</groupId>
                <artifactId>log4j</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
</dependencies>
</project>
Daniel Cerecedo
  • 6,071
  • 4
  • 38
  • 51

2 Answers2

2

Eventually, I had an error in the code where the service was being instantiated explicitly, using new, instead of relying on Spring's CDI. Hence, the @Autowire in of the Repository in the Service was not being processed by Spring.

WRONG

//explicit instantiation. Spring not in charge so no repo injected
setService(new MyService());

RIGHT

//Spring CDI takes charge and autowires the Service and it's dependencies
@Autowired
private MyService myService;

public void someMethod(){
  setService(myService);
}
Daniel Cerecedo
  • 6,071
  • 4
  • 38
  • 51
0

Change your MyRepository class as follows:

public interface MyRepository extends   JpaRepository<AnEntity, Long> {
    public AnEntity findOneByData(String data);
    public AnEntity findOneByIndex(String index);
}
Rohan Kushwaha
  • 738
  • 6
  • 18
  • 1
    It is not really necessary to make explicit the base package to scan. The annotation by default starts at its package and scans upwards (towards the leaves) in the tree of packages. And if finding the Repository was the case, Spring throws an error indicating an unsatisfied dependency that could not wire. Which is not the case, as the application starts up. – Daniel Cerecedo Jan 13 '16 at 11:31