I read this stackoverflow post which says that we don't need to use @EnableJpaRepository
or @EntityScan
Spring data repository works without annotations
I'm not sure what's wrong. But my Spring Boot application is only able to start with @EnableJpaRepository
and @ComponentScan
.
MyApplication.java
package com.domain.spring.example;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
@SpringBootApplication
@ComponentScan("com.domain.spring.example.repository")
@EnableJpaRepositories(
basePackages = "com.domain.spring.example.model",
entityManagerFactoryRef = "entityManagerFactory"
)
public class MyApplication {
public static void main(String[] args) {
new SpringApplicationBuilder(MyApplication.class).run(args);
}
}
Item.java
package com.domain.spring.example.model;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;
import java.math.BigDecimal;
import java.util.UUID;
import jakarta.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.experimental.SuperBuilder;
import org.hibernate.annotations.GenericGenerator;
@Entity
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@SuperBuilder
@Table(name = "items")
public class Item {
@Id
@GeneratedValue(generator = "UUID")
@GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator")
private UUID id;
private String name;
private BigDecimal price;
}
ItemRepository.java
package com.domain.spring.example.respository;
import com.domain.spring.example.model.Item;
import java.util.UUID;
import org.springframework.data.jpa.repository.JpaRepository;
public interface ItemRepository extends JpaRepository<Item, UUID> {
}
ItemService.java
package com.domain.spring.example.service;
import com.domain.spring.example.respository.ItemRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
@Service
@RequiredArgsConstructor
public class ItemService {
private final ItemRepository itemRepository;
}
build.gradle
plugins {
id 'java'
id 'io.spring.dependency-management' version '1.0.8.RELEASE'
id 'org.springframework.boot' version '2.6.4'
}
group 'com.domain'
version '1.0-SNAPSHOT'
repositories {
mavenCentral()
}
configurations {
testIntegrationImplementation.extendsFrom implementation
testIntegrationRuntimeOnly.extendsFrom runtimeOnly
}
dependencies {
annotationProcessor group: 'org.hibernate', name: 'hibernate-jpamodelgen'
annotationProcessor group: 'org.projectlombok', name: 'lombok', version: '1.18.22'
testAnnotationProcessor group: 'org.projectlombok', name: 'lombok', version: '1.18.22'
implementation group: 'com.vladmihalcea', name: 'hibernate-types-52', version: '2.14.0'
implementation group: 'jakarta.persistence', name: 'jakarta.persistence-api', version: '3.1.0-RC2'
implementation group: 'javax.persistence', name: 'javax.persistence-api', version: '2.2'
implementation group: 'javax.validation', name: 'validation-api', version: '2.0.1.Final'
implementation group: 'org.hibernate', name: 'hibernate-core'
implementation group: 'org.springframework.boot', name: 'spring-boot-starter-actuator'
implementation group: 'org.springframework.boot', name: 'spring-boot-starter-data-jpa'
implementation group: 'org.springframework.boot', name: 'spring-boot-starter-webflux'
implementation group: 'org.springframework.boot', name: 'spring-boot-starter-validation'
implementation group: 'org.springframework.cloud', name: 'spring-cloud-starter-netflix-eureka-client', version: '3.1.1'
// implementation group: 'org.springframework.data', name: 'spring-data-jpa'
implementation group: 'org.springframework.data', name: 'spring-data-redis'
implementation group: 'org.projectlombok', name: 'lombok', version: '1.18.22'
implementation group: 'org.postgresql', name: 'postgresql'
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.9.0'
testImplementation group: 'org.springframework.boot', name: 'spring-boot-starter-test'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.9.0'
testIntegrationImplementation group: 'org.springframework.boot', name: 'spring-boot-starter-test'
}
test {
useJUnitPlatform()
}
application.properties
# Eureka
eureka.client.enabled=false
eureka.client.fetch-registry=true
eureka.client.register-with-eureka=true
eureka.client.service-url.defaultZone=http://localhost:4001/eureka/
eureka.instance.prefer-ip-address=true
spring.datasource.platform=postgres
spring.datasource.url=jdbc:postgresql://localhost/example
spring.datasource.username=postgres
spring.datasource.password=123
spring.jpa.generate-ddl=true
spring.jpa.hibernate.ddl-auto=create
spring.jpa.properties.hibernate.check_nullability=true
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
spring.jpa.properties.hibernate.jdbc.batch_size=100
spring.jpa.properties.hibernate.temp.use_jdbc_metadata_defaults=false
# Logging
logging.level.org.springframework.web=DEBUG
logging.level.org.springframework.boot.autoconfigure.web.reactive.error.AbstractErrorWebExceptionHandler=OFF
logging.level.org.springframework.web.HttpLogging=OFF
Without the @EnableJpaRepositories
annotation in MyApplication.java
. I get the following error
Caused by: java.lang.IllegalArgumentException: Not a managed type: class com.domain.spring.example.model.Item
Without the @ComponenctScan
annotation in MyApplication.java
. I get the following error
Parameter 0 of constructor in com.domain.spring.example.service.ItemService required a bean of type 'com.domain.spring.example.respository.ItemRepository' that could not be found.
In addition, the ddl-auto=create
property doesn't work as well.
How to fix it so that I can use the default Spring JPA without adding annotations?
Update:
I think there can be any problem somewhere that prevents Spring to correctly scan repositories, entities, and also routes. This simple route returns 404 when I hit GET /v1/test
package com.domain.spring.example.controller;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Mono;
@RestController
@RequestMapping("/v1")
@RequiredArgsConstructor
public class MyController {
@GetMapping("/test")
public Mono<String> test() {
return Mono.just("test");
}
}
CodePudding user response:
You are looking for repositories in this package
@EnableJpaRepositories(
basePackages = "com.domain.spring.example.model"
but your repository is in this package
com.domain.spring.example.respository
CodePudding user response:
Two things here:
@EnableJpaRepositories(
basePackages = "com.domain.spring.example.respository",
entityManagerFactoryRef = "entityManagerFactory"
)
also since you're using SpringBoot Application, it's auto wiring should take care of instantiating repositories provided the class annotated with @SpringBootApplication
is in a top level package, which you have, so I think you should try without the @EnableJpaRepositories
too.