I finished creating a simple Spring-boot project in which I can enter users and through the Get command it returns me the name (from a list of identical names) with the oldest entry date. Unfortunately, every time I ask for Get it returns this ERROR:
D:\>curl -G localhost:8080/demo/first?=Biagio
{"timestamp":"2020-10-04T22:46:35.996+00:00","status":404,"error":"Not Found","message":"","path":"/demo/first"}
And to each of my POST / Add requests like this ERROR:
D:\>curl localhost:8080/demo/add -d name=Giovanni -d email=giovanni#gmail.com -d surname=Jackie
{"timestamp":"2020-10-04T22:40:51.928+00:00","status":404,"error":"Not Found","message":"","path":"/demo/add"}
Below I enter the interested parties of my project to try to get something out of it, because I have been stuck for days now
AccessingDataMysqlApplication.java
package com.example.accessingdatamysql;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.context.annotation.ComponentScan;
#SpringBootApplication
public class AccessingDataMysqlApplication {
public static void main(String[] args) {
SpringApplication.run(AccessingDataMysqlApplication.class, args);
}
}
MainController.java
package com.example.accessingdatamysql.rest;
import javax.persistence.NoResultException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.example.accessingdatamysql.model.UserDto;
import com.example.accessingdatamysql.service.UserService;
#RestController
#RequestMapping("/demo")
public class MainController {
#Autowired
private UserService userService;
#Transactional
//#RequestMapping(value = "/add/", method = RequestMethod.POST)
#PostMapping(path="/demo/add")
public String addNewUser(#PathVariable("name") String name, #PathVariable("email") String email,
#PathVariable("surname") String surname) {
UserDto n = new UserDto();
n.setName(name);
n.setSurname(surname);
n.setEmail(email);
userService.create(n);
return "User Saved in DB";
}
#SuppressWarnings({ "rawtypes", "unchecked" })
//#RequestMapping(value = "/fetchUser/{name}", method = RequestMethod.GET)
#GetMapping("/demo/first")
public ResponseEntity<UserDto> fetchUser(#PathVariable("name") String name) {
System.out.println(name);
try {
UserDto namefound = userService.findFirstByName(name);
System.out.println("Name found");
ResponseEntity<UserDto> user = new ResponseEntity<UserDto>(namefound, HttpStatus.OK);
return user;
} catch(NoResultException ne) {
System.out.println("User not found");
return new ResponseEntity("User not found with name : " + name, HttpStatus.NOT_FOUND);
}
}
}
UserService.java
package com.example.accessingdatamysql.service;
import org.springframework.stereotype.Service;
import com.example.accessingdatamysql.model.UserDto;
#Service
public interface UserService {
UserDto findFirstByName(String name);
void create(UserDto user);
}
UserServiceImpl.java
package com.example.accessingdatamysql.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import com.example.accessingdatamysql.model.UserDto;
import com.example.accessingdatamysql.model.UserEntity;
import com.example.accessingdatamysql.repo.UserRepository;
import com.example.accessingdatamysql.util.UserMapper;
#Service
public class UserServiceImpl implements UserService {
#Autowired
private UserRepository userRepository;
#Autowired
UserMapper mapper;
#Override
public UserDto findFirstByName(String name) {
UserEntity entity = userRepository.findFirstByName(name);
return mapper.toDtoMapper(entity);
}
#Override
public void create(UserDto user) {
UserEntity entity = mapper.toEntityMapper(user);
userRepository.create(entity);
}
}
UserMapper.java
package com.example.accessingdatamysql.util;
import org.mapstruct.Mapper;
import com.example.accessingdatamysql.model.UserDto;
import com.example.accessingdatamysql.model.UserEntity;
#Mapper(componentModel = "spring")
public interface UserMapper {
public UserEntity toEntityMapper (UserDto user);
public UserDto toDtoMapper (UserEntity userEntity);
}
UserRepository.java
package com.example.accessingdatamysql.repo;
import org.springframework.stereotype.Repository;
import com.example.accessingdatamysql.model.UserEntity;
#Repository
public interface UserRepository {
UserEntity findFirstByName(String name);
void create(UserEntity entity);
}
UserRepositoryImpl.java
package com.example.accessingdatamysql.service;
import javax.persistence.EntityManager;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import org.springframework.stereotype.Component;
import com.example.accessingdatamysql.model.UserEntity;
import com.example.accessingdatamysql.repo.UserRepository;
#Component
public class UserRepositoryImpl implements UserRepository {
private final EntityManager em;
public UserRepositoryImpl(EntityManager entityManager) {
this.em = entityManager;
}
#Override
public UserEntity findFirstByName(String name) {
CriteriaBuilder builder = em.getCriteriaBuilder();
CriteriaQuery<UserEntity> criteria = builder.createQuery(UserEntity.class);
Root<UserEntity> root = criteria.from(UserEntity.class);
criteria.select(root).where(builder.equal(root.get("name"), name));
criteria.orderBy(builder.asc(root.get("timestamp")));
TypedQuery<UserEntity> query = em.createQuery(criteria).setMaxResults(1);
return query.getSingleResult();
}
#Override
// per la creazione//
public void create(UserEntity entity) {
em.persist(entity);
}
}
UserDto.java
package com.example.accessingdatamysql.model;
import java.io.Serializable;
import java.sql.Timestamp;
public class UserDto implements Serializable {
/**
*
*/
private static final long serialVersionUID = -7621330660870602403L;
/**
*
*/
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Timestamp getTimestamp() {
return timestamp;
}
public void setTimestamp(Timestamp timestamp) {
this.timestamp = timestamp;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getSurname() {
return surname;
}
public void setSurname(String surname) {
this.surname = surname;
}
private Timestamp timestamp;
private String email;
private String surname;
}
If you need I can also insert User.java and the pom, but the pom has no problems as the dependencies are all correct.
You have an additional demo in your path descriptions for GET and POST methods, you should remove it:
#GetMapping("/demo/first")
#PostMapping(path = "/demo/first")
It should be :
#GetMapping("/first")
#PostMapping(path = "/first")
This because you have already defined demo in the RequestMapping annotation in the class level.
Related
This is User class, which serves as the Entity.
package com.userproject.Entities;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
#Entity
#Table(name = "userservice")
public class User {
#Id
#Column(name="userID")
int userId;
#Column(name="username")
String username;
#Column(name="age")
int age;
public User(int userId, String username, int age) {
super();
this.userId = userId;
this.username = username;
this.age = age;
}
public User() {
super();
// TODO Auto-generated constructor stub
}
#Override
public String toString() {
return "User [userId=" + userId + ", username=" + username + ", age=" + age + "]";
}
public int getUserId() {
return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
This is my repository interface
package com.userproject.dao;
import org.springframework.data.jpa.repository.JpaRepository;
import com.userproject.Entities.User;
public interface UserRepository extends JpaRepository<User, Integer> {
public User findById(int id);
}
This is my Service class
package com.userproject.Service;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.userproject.Entities.User;
import com.userproject.dao.UserRepository;
#Service
public class UserService {
#Autowired
private UserRepository userRepository;
public User addUser(User usr) {
User savedUser = this.userRepository.save(usr);
return savedUser;
}
public List<User> getAllInfo(){
Iterable<User> allUsers = this.userRepository.findAll();
return (List<User>)allUsers;
}
public User getUser(int usrId) {
User usr = this.userRepository.findById(usrId);
if (usr == null)
throw new NullPointerException();
return usr;
}
}
This is my Controller
package com.userproject.Controllers;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
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.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.userproject.Entities.User;
import com.userproject.Service.UserService;
#RestController
#RequestMapping("/user")
public class UserController {
#Autowired
private UserService service;
#PostMapping("/add")
public ResponseEntity<User> addUser(#RequestBody User u){
try {
User addUser = this.service.addUser(u);
return ResponseEntity.ok(addUser);
} catch(Exception e) {
e.printStackTrace();
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
}
}
#GetMapping("/{id}")
public ResponseEntity<User> getUserById(#PathVariable("id") int userID){
try {
User u = this.service.getUser(userID);
return ResponseEntity.ok(u);
} catch(NullPointerException e) {
e.printStackTrace();
return ResponseEntity.status(HttpStatus.NOT_FOUND).build();
} catch (Exception e) {
e.printStackTrace();
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
}
}
#GetMapping("/all")
public ResponseEntity<List<User>> getAllUsers(){
try {
return ResponseEntity.ok(this.service.getAllInfo());
} catch(Exception e) {
e.printStackTrace();
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
}
}
}
This is my main application class
package com.userproject;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
#EnableJpaRepositories("com.userproject.dao")
#SpringBootApplication(exclude = {DataSourceAutoConfiguration.class })
public class UserProjectApplication {
public static void main(String[] args) {
SpringApplication.run(UserProjectApplication.class, args);
}
}
This is application.properties file
spring.jpa.database=mysql
spring.datasource.username=*****
spring.datasource.password=*****
spring.datasource.url=jdbc:mysql://*******:3306/practice
spring.datasource.driver-class-name= com.mysql.jdbc.Driver
spring.jooq.sql-dialect = org.hibernate.dialect.MySQL57Dialect
spring.jpa.hibernate.ddl-auto= update
This is my project structure:
(https://i.stack.imgur.com/UR10B.png)
When I try to run the application, I keep getting the following message: `
Description:
Field userRepository in com.userproject.Service.UserService required a bean named 'entityManagerFactory' that could not be found.
The injection point has the following annotations:
- #org.springframework.beans.factory.annotation.Autowired(required=true)
Action:
Consider defining a bean named 'entityManagerFactory' in your configuration.
If I remove the "exclude" parameter from #SpringBootApplication, it throws an error stating the datasource cannot be configured as the url is missing.
If I remove the #EnableJpaRepositories, it throws an error stating my userRepository field in Service class cannot be configured.
From what I understand, this whole problem arises from me trying to autowire the userRepository field (which is actually an interface) in the Service class. However, SpringBoot shall be able to do that with the help of proxy classes.
Please provide me with a solution to this.
I've built a spring boot rest api. However, when I try to test it in Postman, I am getting a 404 error. I have linked the code below. Please note that there might be a random #component annotation in some files. This was my tired brain trying anything it can.
Student.java
package StudentModel;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
#Data
#AllArgsConstructor
#NoArgsConstructor
#Entity
#Table(name = "Student")
public class Student {
public enum status {
PAID,
UNPAID,
PARTIAL
}
#Column
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private long Id;
#Column(nullable = false)
private String FirstName;
#Column(nullable = false)
private String LastName;
#Column(nullable = false)
private long Phone;
#Column(nullable = false)
private String Email;
#Column(nullable = false)
private status PaymentStatus;
public long getId() {
return Id;
}
public void setId(long id) {
Id = id;
}
public String getFirstName() {
return FirstName;
}
public void setFirstName(String firstName) {
FirstName = firstName;
}
public String getLastName() {
return LastName;
}
public void setLastName(String lastName) {
LastName = lastName;
}
public long getPhone() {
return Phone;
}
public void setPhone(long phone) {
Phone = phone;
}
public String getEmail() {
return Email;
}
public void setEmail(String email) {
Email = email;
}
public status getPaymentStatus() {
return PaymentStatus;
}
public void setPaymentStatus(status paymentStatus) {
PaymentStatus = paymentStatus;
}
}
StudentController.java
package StudentController;
import java.util.List;
import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import StudentModel.Student;
import StudentService.StudentService;
#Component
#RestController
#RequestMapping("/api/v1")
public class StudentController {
#Autowired
private StudentService studentService;
#PostMapping("/api/v1/addStudent")
public Student addStudent(#RequestBody Student student) {
return studentService.saveStudent(student);
}
#PostMapping("/api/v1/addStudents")
public List<Student> addStudents(#RequestBody List<Student> students) {
return studentService.saveStudents(students);
}
#GetMapping("/api/v1/students")
public List<Student> findAllStudents(){
return studentService.getStudents();
}
#GetMapping("/api/v1/students/{id}")
public Student findStudentById(#PathVariable long id) {
return studentService.getStudentById(id);
}
#GetMapping("/api/v1/students/{name}")
public Student findStudentByFirstName(#PathVariable String FirstName) {
return studentService.getStudentByFirstName(FirstName);
}
#PutMapping("/api/v1/update")
public Student updateStudent(#RequestBody Student student) {
return studentService.updateStudent(student);
}
#DeleteMapping("/api/v1/delete/{id}")
public String deleteStudent(#PathVariable long id) {
return studentService.deleteStudent(id);
}
}
StudentService.java
package StudentService;
import java.util.List;
import java.util.Optional;
import javax.transaction.Transactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import StudentModel.Student;
import StudentRepository.StudentRepository;
#Component
#Service
#Transactional
public class StudentService {
#Autowired
private StudentRepository studentRepository;
public Student saveStudent(Student student) {
return studentRepository.save(student);
}
public List<Student> saveStudents(List<Student> students) {
return studentRepository.saveAll(students);
}
public List<Student> getStudents() {
return studentRepository.findAll();
}
public Student getStudentById(long id){
return studentRepository.getById(id);
}
public Student getStudentByFirstName(String FirstName){
return studentRepository.findByFirstName(FirstName);
}
public Student getStudentByLastName(String LastName){
return studentRepository.findByLastName(LastName);
}
public Student getStudentByEmail(String Email){
return studentRepository.findByEmail(Email);
}
public Student getStudentByPhone(long Phone){
return studentRepository.findByPhone(Phone);
}
public String deleteStudent(long id) {
studentRepository.deleteById(id);
return "Student Deleted";
}
public Student updateStudent (Student student) {
Student existingStudent = studentRepository.getById(student.getId());
existingStudent.setFirstName(student.getFirstName());
existingStudent.setLastName(student.getLastName());
existingStudent.setEmail(student.getEmail());
existingStudent.setPhone(student.getPhone());
existingStudent.setPaymentStatus(student.getPaymentStatus());
return studentRepository.save(existingStudent);
}
}
StudentRepository.java
package StudentRepository;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Component;
import StudentModel.Student;
#Component
public interface StudentRepository extends JpaRepository <Student, Long>{
// Student saveStudent (Student student);
Student findByFirstName(String FirstName);
Student findByLastName(String LastName);
Student findByEmail(String Email);
Student findByPhone(long Phone);
// Student findById(long id);
}
StudentApplication.java
package com.BusyQA;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
#SpringBootApplication
#ComponentScan
public class BusyQaApplication extends SpringBootServletInitializer{
public static void main(String[] args) {
SpringApplication.run(BusyQaApplication.class, args);
}
}
Any help would be greatly appreciated. Thank you.
To make it work, you need some improvements:
For Controller (REST API requests):
remove #Component annotation;
remove /api/v1/ from request mappings;
add DTO to only transfer the required information;
fix the name of the variables, following the convention.
import java.util.ArrayList;
import java.util.List;
import com.example.demo.dto.StudentDTO;
import com.example.demo.entity.Student;
import com.example.demo.service.StudentService;
import org.springframework.web.bind.annotation.*;
#RestController
#RequestMapping("/api/v1")
public class StudentController {
private final StudentService studentService;
public StudentController(StudentService studentService) {
this.studentService = studentService;
}
#PostMapping("/addStudent")
public Student addStudent(#RequestBody StudentDTO studentDTO) {
Student student = new Student(studentDTO);
return studentService.saveStudent(student);
}
#PostMapping("/addStudents")
public List<Student> addStudents(#RequestBody List<Student> students) {
return studentService.saveStudents(students);
}
#GetMapping("/students")
public List<StudentDTO> findAllStudents() {
List<StudentDTO> studentDTOList = new ArrayList<>();
List<Student> studentList = studentService.getStudents();
for (Student student : studentList) {
StudentDTO studentDTO = new StudentDTO(student);
studentDTOList.add(studentDTO);
}
return studentDTOList;
}
#GetMapping("/students/id/{id}")
public Student findStudentById(#PathVariable long id) {
return studentService.getStudentById(id);
}
#GetMapping("/students/firstName/{firstName}")
public Student findStudentByFirstName(#PathVariable String firstName) {
return studentService.getStudentByFirstName(firstName);
}
#PutMapping("/update")
public Student updateStudent(#RequestBody StudentDTO studentDTO) {
Student student = new Student(studentDTO);
return studentService.updateStudent(student);
}
#DeleteMapping("/delete/{id}")
public String deleteStudent(#PathVariable long id) {
return studentService.deleteStudent(id);
}
}
For Service class (Business logic):
remove #Component annotation;
remove #Transactional annotation;
use findById() to retrieve an entity by its Id;
import java.util.List;
import java.util.Optional;
import com.example.demo.entity.Student;
import com.example.demo.repository.StudentRepository;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.persistence.EntityNotFoundException;
#Service
public class StudentService {
private final StudentRepository studentRepository;
public StudentService(StudentRepository studentRepository) {
this.studentRepository = studentRepository;
}
public Student saveStudent(Student student) {
return studentRepository.save(student);
}
public List<Student> saveStudents(List<Student> students) {
return studentRepository.saveAll(students);
}
public List<Student> getStudents() {
return studentRepository.findAll();
}
public Student getStudentById(long id) {
return studentRepository.findById(id).orElseThrow(EntityNotFoundException::new);
}
public Student getStudentByFirstName(String firstName) {
return studentRepository.findByFirstName(firstName);
}
public Student getStudentByLastName(String lastName) {
return studentRepository.findByLastName(lastName);
}
public Student getStudentByEmail(String email) {
return studentRepository.findByEmail(email);
}
public Student getStudentByPhone(long phone) {
return studentRepository.findByPhone(phone);
}
public String deleteStudent(long id) {
studentRepository.deleteById(id);
return "Student Deleted";
}
public Student updateStudent(Student student) {
Student existingStudent = studentRepository.getById(student.getId());
existingStudent.setFirstName(student.getFirstName());
existingStudent.setLastName(student.getLastName());
existingStudent.setEmail(student.getEmail());
existingStudent.setPhone(student.getPhone());
existingStudent.setPaymentStatus(student.getPaymentStatus());
return studentRepository.save(existingStudent);
}
}
The Model class:
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import com.example.demo.dto.StudentDTO;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.Builder;
#Data
#Builder
#AllArgsConstructor
#NoArgsConstructor
#Entity
public class Student {
public Student(StudentDTO studentDTO) {
this.id = studentDTO.getId();
this.firstName = studentDTO.getFirstName();
this.lastName = studentDTO.getLastName();
this.phone = studentDTO.getPhone();
this.email = studentDTO.getEmail();
this.paymentStatus = studentDTO.getPaymentStatus();
}
public enum Status {
PAID,
UNPAID,
PARTIAL
}
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column
private long id;
private String firstName;
private String lastName;
private long phone;
private String email;
private Status paymentStatus;
}
DTO class:
import com.example.demo.entity.Student;
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import static com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL;
#Builder
#Data
#NoArgsConstructor
#AllArgsConstructor
#JsonInclude(NON_NULL)
public class StudentDTO implements Serializable {
public StudentDTO(Student student) {
this.id = student.getId();
this.firstName = student.getFirstName();
this.lastName = student.getLastName();
this.phone = student.getPhone();
this.email = student.getEmail();
this.paymentStatus = student.getPaymentStatus();
}
private long id;
private String firstName;
private String lastName;
private long phone;
private String email;
private Student.Status paymentStatus;
}
The Repository class:
import com.example.demo.entity.Student;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
#Repository
public interface StudentRepository extends JpaRepository<Student, Long> {
Student findByFirstName(String firstName);
Student findByLastName(String lastName);
Student findByEmail(String email);
Student findByPhone(long phone);
}
and the main class of a Spring Boot application:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
To test it, you can use endpoints by the same principle:
POST: localhost:8080/api/v1/addStudent
POST: localhost:8080/api/v1/addStudents
GET: localhost:8080/api/v1/students
GET: localhost:8080/api/v1/students/id/1
GET: localhost:8080/api/v1/students/firstName/testName
PUT: localhost:8080/api/v1/update
DELETE: localhost:8080/api/v1/delete/1
As Dilermando mentioned in the comments, your #RequestMapping("/api/v1") is setting its mapping, then you're extending onto that with #PostMapping("/api/v1/addStudent") making the address {url}/api/v1/api/v1/addStudent. You can resolve this by removing the /api/v1 from the Post/get mappings:
#RequestMapping("/api/v1")
public class StudentController {
#Autowired
private StudentService studentService;
#PostMapping("/addStudent")
public Student addStudent(#RequestBody Student student) {
return studentService.saveStudent(student);
}
...etc
}
There are 2 reason behind 404 not found
Problem 1
You main class is in com.BusyQA package and Controller class is in StudentController package so you have to scan controller class in main class.
Your StudentApplication.java class should become:
#SpringBootApplication
#ComponentScan(basePackageClasses = StudentController.class) // Scan the controller class in main class.
public class BusyQaApplication extends SpringBootServletInitializer{
public static void main(String[] args) {
SpringApplication.run(BusyQaApplication.class, args);
}
}
Problem 2
Remove pre path /api/v1 from all url mapping in controller. Now your mapping url should become
#RestController
#RequestMapping("/api/v1")
public class StudentController {
#Autowired
private StudentService studentService;
#PostMapping("/addStudent")
#PostMapping("/addStudents")
#GetMapping("/students")
#GetMapping("/students/{id}")
#GetMapping("/students/{name}")
#PutMapping("/update")
#DeleteMapping("/delete/{id}")
}
This is another mistake in your code:
Remove the #Component annotation from controller.
Remove the #Component annotation from Service class.
Remove the #Component annotation from Repository interface and add #Repository annotation.
I am new to spring boot and i am creating a spring boot app to generate csv files from data fetched from database .I'm using h2 database for it and want to get selective columns from my entity-id,amount
entity class:
package com.reports.entities;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
#Entity(name="reportDetails")
#Table(name = "reports")
public class Report {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name="id")
private long id;
#Column(name="name")
private String name;
#Column(name="email")
private String email;
#Column(name="amount")
private int amount;
public Report() {
super();
}
public Report(int id, String name, String email, int amount) {
super();
this.id = id;
this.name = name;
this.email = email;
this.amount = amount;
}
public long getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public int getAmount() {
return amount;
}
public void setAmount(int amount) {
this.amount = amount;
}
}
main class:
package com.reports;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import com.reports.entities.Report;
import com.reports.repository.ReportsRepository;
#SpringBootApplication
public class ExportCsvApplication implements CommandLineRunner {
#Autowired
ReportsRepository reportsRepository;
public static void main(String[] args) {
SpringApplication.run(ExportCsvApplication.class, args);
}
#Override
public void run(String... args) throws Exception {
List<Report> reports = new ArrayList<>();
// create dummy employees
reports.add(new Report(1,"roy","roy#123.com",2500));
reports.add(new Report(2,"joy","joy#123.com",2500));
reports.add(new Report(3,"soy","soy#123.com",2500));
reports.add(new Report(4,"moy","moy#123.com",2500));
reports.add(new Report(5,"noy","noy#123.com",2500));
reportsRepository.saveAll(reports);
}
}
repository :
package com.reports.repository;
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;
import com.reports.entities.IReport;
import com.reports.entities.Report;
#Repository("reportsRepository")
public interface ReportsRepository extends JpaRepository<Report,Long>{
}
Service class:
package com.reports.services;
import java.util.List;
import javax.transaction.Transactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.reports.entities.IReport;
import com.reports.entities.Report;
import com.reports.repository.ReportsRepository;
#Transactional
#Service
public class ReportsService {
#Autowired
ReportsRepository reportsRepository;
public List<Report> fetchAll() {
return (List<Report>) reportsRepository.findAll();
}
}
Controller:
package com.reports.controllers;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import com.opencsv.CSVWriter;
import com.opencsv.bean.StatefulBeanToCsv;
import com.opencsv.bean.StatefulBeanToCsvBuilder;
import com.reports.entities.Report;
import com.reports.services.ReportsService;
#RestController
public class ReportsController {
#Autowired
ReportsService reportsService;
#GetMapping("/export-report")
public void exportCSV(HttpServletResponse response) throws Exception {
// set file name and content type
String filename = "details.csv";
response.setContentType("text/csv");
response.setHeader(HttpHeaders.CONTENT_DISPOSITION,
"attachment; filename=\"" + filename + "\"");
// create a csv writer
StatefulBeanToCsv<Report> writer = new StatefulBeanToCsvBuilder<Report>(response.getWriter()).withQuotechar(CSVWriter.NO_QUOTE_CHARACTER).withSeparator(CSVWriter.DEFAULT_SEPARATOR).withOrderedResults(false).build();
// write all employees to csv file
writer.write(reportsService.fetchAll());
}
}
I want to know what would be the best method to incorporate for it i tried query but faced errors.Please let me know how do i get this done
This is more of being related to the opencsv library than Spring or Spring Boot itself.
When constructing the StatefullBeanToCsvBuilder, you should use the withIgonreField builder property to instruct the final StatefullBeanToCsv on which fields to ignore for which types.
Say you want only the id and amount fields out of your Report entity, you can achieve this as follows:
#RestController
public class ReportsController {
#Autowired
ReportsService reportsService;
#GetMapping("/export-report")
public void exportCSV(HttpServletResponse response) throws Exception {
// set file name and content type
String filename = "details.csv";
response.setContentType("text/csv");
response.setHeader(HttpHeaders.CONTENT_DISPOSITION,
"attachment; filename=\"" + filename + "\"");
// Configure the CSV writer builder
StatefulBeanToCsvBuilder<Report> builder = new StatefulBeanToCsvBuilder<Report>(response.getWriter()).withQuotechar(CSVWriter.NO_QUOTE_CHARACTER).withSeparator(CSVWriter.DEFAULT_SEPARATOR).withOrderedResults(false);
// Ignore any field except the `id` and `amount` ones
Arrays.stream(Report.class.getDeclaredFields())
.filter(field -> !("id".equals(field.getName()) || "amount".equals(field.getName())))
.forEach(field -> builder.withIgnoreField(Report.class, field));
// create a csv writer
StatefulBeanToCsv<Report> writer = builder.build();
// write all employees to csv file
writer.write(reportsService.fetchAll());
}
}
I tried to add One To Many Annotation to my spring boot project, but when I run my project I get "Failed to execute CommandLineRunner " error.
I wanted users in the user's table to have more than one city. So, I tried to add OneToMany Annotation.
You can see the error at the attachment.
User Class
package io.javabrains.springsecurity.jpa.models;
import com.spring.weather.*;
import java.util.*;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.OneToMany;
import javax.persistence.Table;
#Entity
#Table(name="app_user")
public class User {
#Id
#GeneratedValue(strategy =GenerationType.AUTO)
private int id;
private String userName;
private String password;
private boolean active;
private String role;
private String city;
#OneToMany(targetEntity = UserCity.class,cascade = CascadeType.ALL)
#JoinTable(name="USER_CITY",joinColumns=#JoinColumn(name="m_user_id"),
inverseJoinColumns=#JoinColumn(name="cityId"))
private List<UserCity> usercity;
public User() {
super();
// TODO Auto-generated constructor stub
}
public List<UserCity> getUsercity() {
return usercity;
}
public void setUsercity(List<UserCity> usercity) {
this.usercity = usercity;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public boolean isActive() {
return active;
}
public void setActive(boolean active) {
this.active = active;
}
public String getRole() {
return role;
}
public void setRole(String role) {
this.role = role;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
}
User City Class
package io.javabrains.springsecurity.jpa.models;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
#Entity
#Table(name="user_city")
public class UserCity {
#Id
#GeneratedValue(strategy =GenerationType.AUTO)
private int cityId;
private String cityName;
public UserCity() {
super();
// TODO Auto-generated constructor stub
}
public UserCity(int cityId, String cityName, User mUser) {
super();
this.cityId = cityId;
this.cityName = cityName;
this.mUser = mUser;
}
#ManyToOne
private User mUser;
public int getCityId() {
return cityId;
}
public void setCityId(int cityId) {
this.cityId = cityId;
}
public String getCityName() {
return cityName;
}
public void setCityName(String cityName) {
this.cityName = cityName;
}
public User getmUser() {
return mUser;
}
public void setmUser(User mUser) {
this.mUser = mUser;
}
}
User Repository
package io.javabrains.springsecurity.jpa;
import java.util.Optional;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import io.javabrains.springsecurity.jpa.models.User;
public interface UserRepository extends JpaRepository<User, Integer> {
Optional<User> findByUserName(String userName);
}
User City Repository
package io.javabrains.springsecurity.jpa;
import org.springframework.data.jpa.repository.JpaRepository;
import io.javabrains.springsecurity.jpa.models.User;
import io.javabrains.springsecurity.jpa.models.UserCity;
public interface CityRepository extends JpaRepository<UserCity,id>{
}
Spring Application Class
package io.javabrains.springsecurity.jpa;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import com.spring.weather.WeatherService;
import io.javabrains.springsecurity.jpa.models.User;
import io.javabrains.springsecurity.jpa.models.UserCity;
#SpringBootApplication
#EnableJpaRepositories(basePackageClasses = UserRepository.class)
public class SpringsecurityApplication implements CommandLineRunner{
#Bean
public WeatherService ws() {
return new WeatherService ();
}
#Autowired
UserRepository userRepository;
CityRepository cityRepository;
public static void main(String[] args) {
SpringApplication.run(SpringsecurityApplication.class, args);
}
#Override
public void run(String... args) throws Exception {
// TODO Auto-generated method stub
System.out.println("Application Running.");
User adminUser= new User();
UserCity ucity=new UserCity();
UserCity ucity2=new UserCity();
ucity.setCityName("amsterdam");
adminUser.setUserName("Admin");
adminUser.setPassword(new BCryptPasswordEncoder().encode("pass"));
adminUser.setRole("ROLE_ADMIN");
adminUser.setActive(true);
adminUser.setCity("bologna");
ucity.setmUser(adminUser);
userRepository.save(adminUser);
cityRepository.save(ucity);
User newUser= new User();
newUser.setUserName("User");
newUser.setPassword(new BCryptPasswordEncoder().encode("pass"));
newUser.setRole("ROLE_USER");
newUser.setActive(true);
newUser.setCity("maribor");
ucity2.setmUser(newUser);
userRepository.save(newUser);
cityRepository.save(ucity2);
}
}
The problem you are encountering, more specifically the NullPointerException at line 54 of your main application, is caused by the fact that the cityRepository is not
instantiated.
Looking through your configuration, I see that you only register the UserRepository with the #EnableJpaRepositories annotation.
Try adding also the CityRepository to the #EnableJpaRepositories, and also specify this bean as a candidate for autowiring( also add #Autowired to this bean, as you did for UserRepository)
For a good practice, following the MVC structure, it would be nice is all your spring repositories, the beans responsible for all CRUD operations with the database to be under the same package
The springboot application exposes the graphql API on the endpoint "localhost:8091/rest/books". When I test it with Postman passing the query in the body as graphQL type it gives error "Invalid Syntax", whereas when I pass the same query as raw text, it yields correct results. I'm using HSQL. The structure of my application is:
The files with their code respectively are:
Book.java
package com.techprimers.graphql.springbootgrapqlexample.model;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
//#AllArgsConstructor
//#NoArgsConstructor
#Setter
#Getter
#Table
#Entity
public class Book {
#Id
private String isn;
public Book() {
super();
}
public Book(String isn, String title, String publisher, String[] authors, String publishedDate) {
super();
this.isn = isn;
this.title = title;
this.publisher = publisher;
this.authors = authors;
this.publishedDate = publishedDate;
}
public String getIsn() {
return isn;
}
public void setIsn(String isn) {
this.isn = isn;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getPublisher() {
return publisher;
}
public void setPublisher(String publisher) {
this.publisher = publisher;
}
public String[] getAuthors() {
return authors;
}
public void setAuthors(String[] authors) {
this.authors = authors;
}
public String getPublishedDate() {
return publishedDate;
}
public void setPublishedDate(String publishedDate) {
this.publishedDate = publishedDate;
}
private String title;
private String publisher;
private String[] authors;
private String publishedDate;
}
BookRepository.java
package com.techprimers.graphql.springbootgrapqlexample.repository;
import com.techprimers.graphql.springbootgrapqlexample.model.Book;
import org.springframework.data.jpa.repository.JpaRepository;
public interface BookRepository extends JpaRepository<Book, String> {
}
BookResource.java
package com.techprimers.graphql.springbootgrapqlexample.resource;
import com.techprimers.graphql.springbootgrapqlexample.service.GraphQLService;
import graphql.ExecutionResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
#CrossOrigin(origins = "http://localhost:3000")
#RequestMapping("/rest/books")
#RestController
public class BookResource {
#Autowired
GraphQLService graphQLService;
#PostMapping
public ResponseEntity<Object> getAllBooks(#RequestBody String query) {
ExecutionResult execute = graphQLService.getGraphQL().execute(query);
return new ResponseEntity<>(execute, HttpStatus.OK);
}
}
AllBooksDataFetcher.java
package com.techprimers.graphql.springbootgrapqlexample.service.datafetcher;
import com.techprimers.graphql.springbootgrapqlexample.model.Book;
import com.techprimers.graphql.springbootgrapqlexample.repository.BookRepository;
import graphql.schema.DataFetcher;
import graphql.schema.DataFetchingEnvironment;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.List;
#Component
public class AllBooksDataFetcher implements DataFetcher<List<Book>>{
#Autowired
BookRepository bookRepository;
#Override
public List<Book> get(DataFetchingEnvironment dataFetchingEnvironment) {
return bookRepository.findAll();
}
}
BookDataFetcher.java
package com.techprimers.graphql.springbootgrapqlexample.service.datafetcher;
import com.techprimers.graphql.springbootgrapqlexample.model.Book;
import com.techprimers.graphql.springbootgrapqlexample.repository.BookRepository;
import graphql.schema.DataFetcher;
import graphql.schema.DataFetchingEnvironment;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
#Component
public class BookDataFetcher implements DataFetcher<Book>{
#Autowired
BookRepository bookRepository;
#Override
public Book get(DataFetchingEnvironment dataFetchingEnvironment) {
String isn = dataFetchingEnvironment.getArgument("id");
return bookRepository.findById(isn).get();
}
}
And in the resources folder is
Books.graphql (contains schema)
schema {
query: Query
}
type Query {
allBooks: [Book]
book(id: String): Book
}
type Book {
isn: String
title: String
publisher: String
authors: [String]
publishedDate: String
}