javaspringspring-bootmavenjpa

My Spring Boot app doesn't identify my entities


I'm trying to run a Spring Boot Application, in where I'm trying to test the display of a list of cars on my Postgres database. The thing is that, when I try to run the app, is shutdowns inmediatly, because is not capable of "creating beans for CocheRepository/CocheService".

2024-06-10T18:41:07.079+02:00 DEBUG 38442 --- [Rental-Car] [           main] o.s.d.r.c.s.RepositoryFactorySupport     : Initializing repository instance for com.example.demo.repository.CocheRepository…
2024-06-10T18:41:07.091+02:00  WARN 38442 --- [Rental-Car] [           main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'cocheController': Unsatisfied dependency expressed through field 'carService': Error creating bean with name 'carServiceImpl': Unsatisfied dependency expressed through field 'repository': Error creating bean with name 'cocheRepository' defined in com.example.demo.repository.CocheRepository defined in @EnableJpaRepositories declared on JpaRepositoriesRegistrar.EnableJpaRepositoriesConfiguration: Not a managed type: class com.example.demo.model.Coche
2024-06-10T18:41:07.091+02:00  INFO 38442 --- [Rental-Car] [           main] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'
2024-06-10T18:41:07.093+02:00  INFO 38442 --- [Rental-Car] [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown initiated...
2024-06-10T18:41:09.257+02:00  INFO 38442 --- [Rental-Car] [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown completed.
2024-06-10T18:41:09.259+02:00  INFO 38442 --- [Rental-Car] [           main] o.apache.catalina.core.StandardService   : Stopping service [Tomcat]

My folder structure looks something like this, as I'm trying to follow the Repository-Service-Controller pattern folder structure

It's a Maven project, and I'm using Ubuntu, in case this information could help. I'm showing you all my code to understand where the error could be in.

Coche.java:

package com.example.demo.model;



@Entity
public class Coche {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id_coche;
    private String modelo;
    private String detalles;
    private double precio;
    private String imagen;

    public Coche() {
    }
    public Coche(String modelo, String detalles, double precio, String imagen) {
        this.modelo = modelo;
        this.detalles = detalles;
        this.precio = precio;
        this.imagen = imagen;
    }

    //getters and setters
}

CocheRepository.java:

package com.example.demo.repository;


@Repository
public interface CocheRepository extends JpaRepository<Coche, Long> {
    @Override
    List<Coche> findAll(Sort sort);
}

CocheService.java (interface):

package com.example.demo.service;

import com.example.demo.model.Coche;



public interface CocheService {
    List<Coche> findAll();
}

CarServiceImpl.java (class):

package com.example.demo.service;

import com.example.demo.model.Coche;
import com.example.demo.repository.CocheRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
@Service
public class CarServiceImpl implements CocheService {
    @Autowired
    private CocheRepository repository;
    @Override
    public List<Coche> findAll() {
        return repository.findAll();
    }
}

RentalCarApplication.java (main):

package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;



@SpringBootApplication
public class RentalCarApplication {

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

I tried changing my JPA Repo to a CRUD Repo, but nothing happened. Also, I tried @EnableJPARepositories on the main App, but also nothing happened. Furthermore, I tried to @ComponentScan, but I am not able to do so, since Spring tells me is redundanct because @SpringBootApplication already does that (I think because of some sort of auto-configuration). I'm expecting to launch the app on localhost to be able to access to an JSON array of cars when I access to http://localhost:8080/api/v1/coches


Solution

  • You have declared id_coche as int. This is equivalent for a primary key field in your table:

    @Entity
    public class Coche {
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private int id_coche;
        
        // (...)
    }
    

    Then you have declared repository CocheRepository that extends JpaRepository<Coche, Long>. You have just said something like this: "Let CocheRepository be a repository that is associated with @Entity Coche which uses primary key of type Long" - which is simply not true.

    Spring tries to inject CocheRepository into CarServiceImpl, but first it needs to create an instance. Spring doesn't know how to create an instance for this, because Coche @Entity uses int instead of Long type as a primary key.

    Try to use below repository:

    @Repository
    public interface CocheRepository extends JpaRepository<Coche, Integer> {
        @Override
        List<Coche> findAll(Sort sort);
    }
    

    Additionally you have to modify your Coche class like below (JpaRepository uses generic type parameters witch can not be a primitive one, so you need to use Integer instead of int):

    @Entity
    public class Coche {
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private Integer id_coche;
        
        // (...)
    }