I am working on a booking application for learning purposes, a problem with a method name in the repository interface
Optional<Room> findByIdAndStatus(int id, status status);
and I am always getting this error:
Error starting ApplicationContext. To display the condition evaluation report re-run your application with 'debug' enabled.
2023-04-12T01:52:06.873+02:00 ERROR 11064 --- [ restartedMain] o.s.boot.SpringApplication : Application run failed
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'roomController': Unsatisfied dependency expressed through field 'roomService': Error creating bean with name 'roomService': Unsatisfied dependency expressed through field 'roomRepository': Error creating bean with name 'roomRepository' defined in com.beClean.soba1.soba1.Repository.RoomRepository defined in @EnableJpaRepositories declared on JpaRepositoriesRegistrar.EnableJpaRepositoriesConfiguration: Could not create query for public abstract java.util.Optional com.beClean.soba1.soba1.Repository.RoomRepository.findByIdAndStatus(int,com.beClean.soba1.soba1.Entities.Room$status); Reason: Failed to create query for method public abstract java.util.Optional com.beClean.soba1.soba1.Repository.RoomRepository.findByIdAndStatus(int,com.beClean.soba1.soba1.Entities.Room$status); No property 'id' found for type 'Room' Did you mean ''tip''
This is my entity file:
package com.beClean.soba1.soba1.Entities;
import java.util.List;
import jakarta.persistence.Entity;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.OneToMany;
import jakarta.persistence.Version;
@Entity(name="soba")
public class Room {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int soba_id;
@ManyToOne
@JoinColumn(name="hotel_id")
Hotel hotel;
private String tip;
private double cena;
private String opis;
public enum status {SLOBODNO, ZAUZETO};
@Enumerated(EnumType.STRING)
private status status;
@OneToMany(mappedBy = "room")
private List<Booking>listaRezervacija;
//@Version
//int versionNumber = 0;
public Room(int soba_id, Hotel hotel, String tip, double cena, String opis,status status) {
this.soba_id = soba_id;
this.hotel = hotel;
this.tip = tip;
this.cena = cena;
this.opis = opis;
this.status = status;
}
public Room() {
}
public int getSoba_id() {
return soba_id;
}
public void setSoba_id(int soba_id) {
this.soba_id = soba_id;
}
public Hotel getHotel() {
return hotel;
}
public void setHotel(Hotel hotel) {
this.hotel = hotel;
}
public String getTip() {
return tip;
}
public void setTip(String tip) {
this.tip = tip;
}
public double getCena() {
return cena;
}
public void setCena(double cena) {
this.cena = cena;
}
public String getOpis() {
return opis;
}
public void setOpis(String opis) {
this.opis = opis;
}
public status getStatus() {
return status;
}
public void setStatus(status status) {
this.status = status;
}
}
This is my repository file:
package com.beClean.soba1.soba1.Repository;
import java.util.List;
import java.util.Optional;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.CrudRepository;
import com.beClean.soba1.soba1.Entities.Room;
import com.beClean.soba1.soba1.Entities.Room.status;
import ch.qos.logback.core.status.Status;
public interface RoomRepository extends CrudRepository<Room, Integer>{
@Query("select s from soba s where s.tip = 'trokrevetna'")
List<Room>findAllTrokrevetna();
@Query("select s from soba s where s.tip = 'dvokrevetna'")
List<Room>findAllDvokrevetna();
//nadji sobe koje su jeftinije od date cene
List<Room>findByCenaLessThan(double cena);
//sortiraj od najjeftinije do najskuplje
List<Room> findByOrderByCenaAsc();
//sortiraj od najskuplje do najjeftinije
List<Room>findByOrderByCenaDesc();
Optional<Room> findById(int id);
List<Room> findByStatus(Status status);
Optional<Room> findByIdAndStatus(int id, status status);
}
this is my service file:
package com.beClean.soba1.soba1.Service;
import java.util.List;
import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.PathVariable;
import com.beClean.soba1.soba1.Entities.Room;
import com.beClean.soba1.soba1.Entities.Room.status;
import com.beClean.soba1.soba1.Repository.RoomRepository;
import ch.qos.logback.core.status.Status;
@Service
public class RoomService {
@Autowired
RoomRepository roomRepository;
public List<Room>getAllRooms(){
return (List<Room>) roomRepository.findAll();
}
public Room getRoomById(int id) {
return getIfPresentOrThrow(roomRepository.findById(id));
}
public List<Room> getAllTrokrevetna(){
return roomRepository.findAllTrokrevetna();
}
public List<Room>getAllDvokrevetna(){
return roomRepository.findAllDvokrevetna();
}
public List<Room> getRoomByCenaLessThan(@PathVariable double cena){
return roomRepository.findByCenaLessThan(cena);
}
public List<Room>getByOrderByCenaAsc(){
return roomRepository.findByOrderByCenaAsc();
}
public List<Room> getByOrderByCenaDesc() {
return roomRepository.findByOrderByCenaDesc();
}
public List<Room>getRoomByStatus(Status status){
return roomRepository.findByStatus(status);
}
private Room getIfPresentOrThrow(Optional<Room> optionalRoom) {
if (!optionalRoom.isPresent()) {
throw new IllegalArgumentException();
}
return optionalRoom.get();
}
public Room getRoomByIdAndStatus(int id, status status) {
return getIfPresentOrThrow(roomRepository.findByIdAndStatus(id, status));
}
}
and the controller file:
package com.beClean.soba1.soba1.Controller;
import java.util.List;
import java.util.Optional;
import org.hibernate.engine.query.spi.ReturnMetadata;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import com.beClean.soba1.soba1.Entities.Room;
import com.beClean.soba1.soba1.Entities.Room.status;
import com.beClean.soba1.soba1.Service.RoomService;
import ch.qos.logback.core.status.Status;
@RestController
public class RoomController {
@Autowired
RoomService roomService;
@GetMapping("/room")
public List<Room>getAllRooms(){
return(List<Room>) roomService.getAllRooms();
}
@GetMapping("/room/{id}")
public Room getRoomById(@PathVariable int id) {
return roomService.getRoomById(id);
}
@GetMapping("/trokrevetna")
public List<Room>getAllTrokrevetna(){
return roomService.getAllTrokrevetna();
}
@GetMapping("/dvokrevetna")
public List<Room>findAlldvokrevetna(){
return roomService.getAllDvokrevetna();
}
@GetMapping("/jeftinije/{cena}")
public List<Room>getRoomByCenaLessThan(@PathVariable double cena){
return roomService.getRoomByCenaLessThan(cena);
}
@GetMapping("/najjeftinije")
public List<Room>getByOrderByCenaAsc(){
return roomService.getByOrderByCenaAsc();
}
@GetMapping("/najskuplje")
public List<Room>GetByOrderByCenaDesc(){
return roomService.getByOrderByCenaDesc();
}
@GetMapping("/{status}")
public List<Room>getRoomByStatus(Status status){
return roomService.getRoomByStatus(status);
}
}
I'm a newbie, I've tried almost everything I could think of with naming, without success.. :( Thanks for the help!
the issue is here
Spring JPA querying is accomplished in two steps: first, use "@Query," followed by your custom query. second is Derived Query Methods which is your case, and it works by name, so when your method
has
findByIdAndStatusSpring will look at the model of the repository, which in your case is Room.java and check for fields calledidandstatus, so if you rename yoursoba_idtoit should be fine, additionally if you want to keep the name soba_id on db level you can apply
@Column(name = "soba_id")and everything is ok