HttpRequestMethodNotSupportedException: Request method 'POST' not supported in Spring API - java

I want to build an API for my Employee entity(table) and when I tried a GET request by id or without id in the URL it works. but when I tried a POST, PUT, PATCH, or DELETE request it will be 405 error. And it looks like this for POST request
2021-11-24 18:42:59.517 DEBUG 4756 [nio-8080-exec-6] o.s.web.servlet.DispatcherServlet :"ERROR" dispatch for POST "/error", parameters={}
2021-11-24 18:42:59.520 WARN 4756---[nio-8080-exec-6] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'POST' not supported]
2021-11-24 18:42:59.520 DEBUG 4756 [nio-8080-exec-6]o.s.web.servlet.DispatcherServlet :Exiting from "ERROR" dispatch, status 405
the api-controlle class looks like
package com.miki.pma.api.controllers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PatchMapping;
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.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
import com.miki.pma.dao.EmployeeRepository;
import com.miki.pma.entity.Employee;
#RestController
#RequestMapping("/app-api/employees")
public class EmployeeApiController {
#Autowired
EmployeeRepository empRepo;
#GetMapping()
public Iterable<Employee> getEmployees(){
return empRepo.findAll();
}
#GetMapping("/{id}")
public Employee getEmployeeById(#PathVariable("id") Long id) {
return empRepo.findById(id).get();
}
#PostMapping(consumes="application/json")
#ResponseStatus(HttpStatus.CREATED)
public Employee create(#RequestBody Employee employee) {
return empRepo.save(employee);
}
#PutMapping(consumes="application/json")
#ResponseStatus(HttpStatus.OK)
public Employee update(#RequestBody Employee employee) {
return empRepo.save(employee);
}
#PatchMapping(value = "/{id}",consumes="application/json")
public Employee partialUpdate(#PathVariable("id") Long id, #RequestBody Employee pathEmployee) {
Employee emp= empRepo.findById(id).get();
if(pathEmployee.getEmail()!= null) {
emp.setEmail(pathEmployee.getEmail());
}
if(pathEmployee.getFirstName()!= null) {
emp.setFirstName(pathEmployee.getFirstName());
}
if(pathEmployee.getLastname()!= null) {
emp.setLastname(pathEmployee.getLastname());
}
return empRepo.save(emp);
}
#DeleteMapping(value="/{id}")
#ResponseStatus(HttpStatus.NO_CONTENT)
public void delete(#PathVariable("id") Long id) {
empRepo.deleteById(id);
}
}
The Employee entity class looks like this
package com.miki.pma.entity;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Column;
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.ManyToMany;
import javax.persistence.SequenceGenerator;
import javax.validation.constraints.Email;
import javax.validation.constraints.Size;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.sun.istack.NotNull;
#Entity
public class Employee {
#Id
#GeneratedValue(strategy= GenerationType.SEQUENCE, generator="employee_seq")
#SequenceGenerator(name = "employee_seq", allocationSize = 1)
private long employeeId;
#NotNull
#Size(min=2, max=50)
private String firstName;
#NotNull
#Size(min=1, max=50)
private String lastname;
#NotNull
#Email
#Column(unique=true)
private String email;
#ManyToMany(cascade= {CascadeType.DETACH,CascadeType.MERGE,CascadeType.PERSIST, CascadeType.REFRESH}
, fetch= FetchType.LAZY)
#JoinTable(name="employee_project",
joinColumns=#JoinColumn(name="employee_id"),
inverseJoinColumns=#JoinColumn(name="project_id"))
#JsonIgnore
private List<Project> projects;
public List<Project> getProjects() {
return projects;
}
public void setProjects(List<Project> projects) {
this.projects = projects;
}
public Employee() {
super();
}
public Employee(String firstName, String lastname, String email) {
super();
this.firstName = firstName;
this.lastname = lastname;
this.email = email;
}
public long getEmployeeId() {
return employeeId;
}
public void setEmployeeId(long employeeId) {
this.employeeId = employeeId;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastname() {
return lastname;
}
public void setLastname(String lastname) {
this.lastname = lastname;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
you can see the post request I have tried in this picture link check it out
Post request from arch
so how can i use the POST,PUT,DELETE and PATCH request

As far as I know, HttpRequestMethodNotSupportedException occurs when your end point is identified but you are sending wrong REST action type. For example, you are sending request with POST which is actually a GET endpoint.
Also, I do not see any specific endpoint defined for POST/PUT/PATCH. Rest endpoints must be action verbs for e.g. baseURL/create -> To create a resource and so on..

Related

how to find students Bydate (findByDate)

I went to develop an application to manage students in a university, I am looking for how to find students in relation to a date entered for that I have developed the following code lines:
1- Model student.java
package com.avatar.model;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
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.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.JoinColumn;
#Entity
#Table(name = "Students")
public class Student{
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private int id;
private String nom;
private String prenom;
private String numTel;
private String mail;
#Temporal(TemporalType.DATE)
private Date dateCurrent;
#ManyToMany(fetch = FetchType.LAZY,
cascade = {
CascadeType.PERSIST,
CascadeType.MERGE
})
#JoinTable(name = "student_techno",
joinColumns = { #JoinColumn(name = "student_id") },
inverseJoinColumns = { #JoinColumn(name = "techno_id") })
private Set<Techno> techno = new HashSet<>();
public Student() {
}
#SuppressWarnings("unchecked")
public Student(String nom, String prenom,String numTel, String mail, Date dateCurrent,
) {
super();
this.nom = nom;
this.prenom = prenom;
this.numTel = numTel;
this.mail = mail;
this.dateCurrent = dateCurrent;
}
public String getNom() {
return nom;
}
public void setNom(String nom) {
this.nom = nom;
}
public String getPrenom() {
return prenom;
}
public void setPrenom(String prenom) {
this.prenom = prenom;
}
public String getNumTel() {
return numTel;
}
public void setNumTel(String numTel) {
this.numTel = numTel;
}
public String getMail() {
return mail;
}
public void setMail(String mail) {
this.mail = mail;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public Date getdateCurrent() {
return dateCurrent;
}
public void setdateCurrent(Date dateCurrent) {
this.dateCurrent = dateCurrent;
}
#Override
public String toString() {
return "Student[nom=" + nom + ", prenom=" + prenom + ", numTel=" + numTel + ", mail="
+ mail + ", dateCurrent=" + dateCurrent+ "]";
}
}
2- Controller
package com.avatar.web;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.bind.annotation.CrossOrigin;
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.avatar.dao.StudentDao;
import com.avatar.model.Student;
#CrossOrigin(origins = "http://localhost:4200")
#RestController
#RequestMapping("/avatar")
public class StudentController {
#Autowired
StudentDao studentdao;
#GetMapping(value = "/all-students")
public List<Student> listeDesStudent() {
List<Student> students= studentdao.findAll();
if (students.isEmpty())
throw new ProductNotFoundException("No student is registered in the database");
return students;
}
#GetMapping(value = "/all-students/dateCurrent/{dateCurrent}")
public List<Student> viewStudent(#PathVariable("dateCurrent") #DateTimeFormat(pattern = "yyyy-MM-dd") Date dateCurrent) {
Calendar c = Calendar.getInstance();
c.setTime(dateCurrent);
c.add(Calendar.DATE, 1);
dateCurrent = c.getTime();
return studentdao.findByDate(dateCurrent);
}
#GetMapping(value = "/all-students /techno/{nomTechno}")
List<Student > viewStudent(#PathVariable("nomTechno") String nomTechno) {
return studentdao.findDistinctByTechnoNomTechno(nomTechno);
}
#PostMapping(value = "/add-student")
public Student addStudent(#RequestBody Student student) {
Student studentAdded= studentdao.save(Student);
return studentAdded;
}
}
3- DAO
package com.avatar.dao;
import java.util.Date;
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import com.avatar.model.Student;
#Repository
public interface StudentDao extends JpaRepository<Student, String> {
List<Student> findByDate(Date dateCurrent);
List<> findDistinctByTechnoNomTechno(String nomTechno);
}
4- applications.properties
server.port= 8080
# MySQL Properties
spring.jpa.show-sql = true
spring.datasource.url= jdbc:mysql://localhost:3306/avatar?serverTimezone=UTC&useLegacyDatetimeCode=false
spring.datasource.username=*****
spring.datasource.password=*****
# Hibernate Properties
spring.jpa.hibernate.ddl-auto=update
in my console i have:
Failed to create query for method public abstract java.util.List com.avatar.dao.StudentDao.findByDate(java.util.Date)! No property date found for type Student!
Please update DAO as per for below mentioned changes
If the field name is dateCurrent then findByDateCurrent.
package com.avatar.dao;
import java.util.Date;
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import com.avatar.model.Student;
#Repository
public interface StudentDao extends JpaRepository<Student, String> {
List<Student> findByDateCurrent(Date dateCurrent);
List<> findDistinctByTechnoNomTechno(String nomTechno);
}
You are missing field name, in Entity class it is not the date by dateCurrent, thus your JPA should be findByDateCurrent

Cannot Resolve Repository Metadata for Customers

I am trying to connect mongodDB with spring boot backend. I've made a small collection by the name of customer in local mongo database. I've already implemented the model, repository class and REST controller which contains end points for GET, POST and DELETE for customer.
Whenever I start the project and try to hit the end point, I get the following error:
Below is the code that I've written:
Customer.java (model class)
package fashion.connect.models;
import org.bson.types.ObjectId;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
#Document(collection= "customers")
public class Customers {
#Id
public ObjectId _id;
public String firstname;
public String lastname;
public Customers() {}
public Customers(ObjectId _id, String firstname, String lastname) {
this._id = _id;
this.firstname= firstname;
this.lastname= lastname;
}
public String get_id() {
return _id.toHexString();
}
public void set_id(ObjectId _id) {
this._id = _id;
}
public String getFirstname() {
return firstname;
}
public void setFirstname(String firstname) {
this.firstname = firstname;
}
public String getLastname() {
return lastname;
}
public void setLastname(String lastname) {
this.lastname = lastname;
}
}
CustomerRepository.java
package fashion.connect.repositories;
import org.bson.types.ObjectId;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.stereotype.Repository;
import fashion.connect.models.Customers;
#Repository
public interface CustomersRepository extends MongoRepository<Customers, String> {
Customers findBy_id(ObjectId _id);
}
CustomerController.java
package fashion.connect.controllers;
import fashion.connect.models.Customers;
import fashion.connect.repositories.CustomersRepository;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import javax.validation.Valid;
import java.util.List;
#RestController
#RequestMapping("/customers")
public class CustomersController {
#Autowired
private CustomersRepository repository;
#RequestMapping(value = "/", method = RequestMethod.GET)
public List<Customers> getAllCusomers() {
return repository.findAll();
}
#RequestMapping(value = "/{id}", method = RequestMethod.GET)
public Customers getCustomertById(#PathVariable("id") ObjectId id) {
return repository.findBy_id(id);
}
#RequestMapping(value = "/{id}", method = RequestMethod.PUT)
public void modifyCustomerById(#PathVariable("id") ObjectId id, #Valid #RequestBody Customers customers) {
customers.set_id(id);
repository.save(customers);
}
#RequestMapping(value = "/", method = RequestMethod.POST)
public Customers createCustomer(#Valid #RequestBody Customers customers) {
customers.set_id(ObjectId.get());
repository.save(customers);
return customers;
}
#RequestMapping(value = "/{id}", method = RequestMethod.DELETE)
public void deleteCustomert(#PathVariable ObjectId id) {
repository.delete(repository.findBy_id(id));
}
Here's the stack trace:
I think the add mongo repositories have to be added to the spring context as with annotation #EnableMongoRepositories:
https://docs.spring.io/spring-data/data-mongodb/docs/current/api/org/springframework/data/mongodb/repository/config/EnableMongoRepositories.html
And then you enter the package of all your mongo repos as base package:
#EnableMongoRepositories(basePackages = "repo.packages")

How to do the CURD operations on Spring Boot Restful API using Sping Data Jpa OneToMany nested model?

I was trying to make a crud app which has two model objects of type Muscle and Exercise. Basically One Muscle Object can have a list of Exercise objects. I wanted to implement the CRUD operations for the both the model object. For Muscle object it was very straight forward but for the Exercise Object for the put/Update operation I am getting the following error "JSON parse error: Unresolved forward references for: ; nested exception is com.fasterxml.jackson.databind.deser.UnresolvedForwardReference" . And further more if I try to delete one exercise, somehow all the data of muscle and exercise gets deleted.
This is my muscle class
package com.fazla.exercise.model;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Column;
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.OneToMany;
import com.fasterxml.jackson.annotation.JsonIdentityInfo;
import com.fasterxml.jackson.annotation.ObjectIdGenerators;
#Entity
#JsonIdentityInfo(generator=ObjectIdGenerators.IntSequenceGenerator.class, property="id")
public class Muscle {
#Id
// #Column(unique = true, nullable = false)
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#Column
private String name;
#OneToMany(mappedBy="muscle", cascade= CascadeType.ALL, fetch = FetchType.EAGER)
// #JoinColumn(name="muscle_id")
// #Column(nullable = true)
private List<Exercise> exercises = new ArrayList<>();
public Muscle() {
}
public Muscle(String name, List<Exercise> exercises) {
super();
this.name = name;
this.exercises = exercises;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Exercise> getExercises() {
return exercises;
}
public void setExercises(List<Exercise> exercises) {
this.exercises = exercises;
}
// #Override
// public String toString() {
// return "Muscle [id=" + id + ", name=" + name + ", exercises=" + exercises + "]";
// }
}
This is my Exercise Object
package com.fazla.exercise.model;
import javax.persistence.CascadeType;
import javax.persistence.Column;
//import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToOne;
import com.fasterxml.jackson.annotation.JsonIdentityInfo;
import com.fasterxml.jackson.annotation.ObjectIdGenerators;
#Entity
//#JsonIdentityInfo(generator=ObjectIdGenerators.IntSequenceGenerator.class, property="id")
public class Exercise {
#Id
#Column(unique = true, nullable = false)
#GeneratedValue(strategy = GenerationType.AUTO)
private long id;
#Column
private String name;
#Column
private String description;
//As there will be many exercise under one muscle that is why manytoone
//object references an unsaved transient instance - save the transient instance before flushing
//that is why need to add the cascading dependencies
#ManyToOne(cascade = CascadeType.ALL)
#JoinColumn(name="muscle_id")
// #JsonIgnore
// #JoinTable(name="muscle")
private Muscle muscle;
public Exercise() {
}
public Exercise(String name, String description, Muscle muscle) {
super();
this.name = name;
this.description = description;
this.muscle = muscle;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Muscle getMuscle() {
return muscle;
}
public void setMuscle(Muscle muscle) {
this.muscle = muscle;
}
// #Override
// public String toString() {
// return "Exercise [id=" + id + ", name=" + name + ", description=" + description + ", muscle=" + muscle + "]";
// }
}
This is the MuscleController
package com.fazla.exercise.controller;
import java.util.List;
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.RestController;
import com.fazla.exercise.model.Muscle;
import com.fazla.exercise.repository.MuscleRepository;
#RestController
public class MuscleController {
private MuscleRepository muscleRepository;
public MuscleController(MuscleRepository muscleRepository) {
this.muscleRepository = muscleRepository;
}
#GetMapping("/muscle")
List<Muscle> all(){
return muscleRepository.findAll();
}
#PostMapping("/muscle")
Muscle newMuscle(#RequestBody Muscle muscle) {
return muscleRepository.save(muscle);
}
#GetMapping("/muscle/{id}")
Muscle one(#PathVariable Long id) {
return muscleRepository.findById(id)
.orElse(null);
}
#PutMapping("/muscle/{id}")
Muscle updateMuscle(#RequestBody Muscle newMuscle, #PathVariable Long id) {
return muscleRepository.findById(id)
.map(muscle ->{
muscle.setName(newMuscle.getName());
muscle.setExercises(newMuscle.getExercises());
return muscleRepository.save(muscle);
})
.orElse(null);
}
#DeleteMapping("/muscle/{id}")
void deleteMuscle(#PathVariable Long id){
muscleRepository.deleteById(id);
}
}
This is the ExerciseController Class
package com.fazla.exercise.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
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.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.fazla.exercise.model.Exercise;
import com.fazla.exercise.model.Muscle;
import com.fazla.exercise.repository.ExerciseRepository;
import com.fazla.exercise.repository.MuscleRepository;
#RestController
public class ExerciseController {
private ExerciseRepository repository;
private MuscleRepository muscleRepository;
#Autowired
public ExerciseController(ExerciseRepository repository, MuscleRepository muscleRepository) {
super();
this.repository = repository;
this.muscleRepository=muscleRepository;
}
#GetMapping("/exercise")
public List<Exercise> getAll() {
return repository.findAll();
}
#PostMapping("/exercise")
public Exercise newExercise(#RequestBody Exercise newExercise, #RequestParam
Long muscleId) {
Muscle muscle = muscleRepository.findById(muscleId).orElse(null);
newExercise.setMuscle(muscle);
return repository.save(newExercise);
}
#DeleteMapping("/exercise/{id}")
public void deleteExercise(#PathVariable Long id) {
repository.deleteById(id);
}
#GetMapping("/exercise/{id}")
public Exercise one(#PathVariable Long id) {
return repository.findById(id).orElse(null);
}
#PutMapping("/exercise/{id}")
public Exercise updateExercise(#RequestBody Exercise newExercise, #PathVariable Long id) {
return repository.findById(id)
.map(//map a function which maps
e ->{
e.setName(newExercise.getName());
e.setDescription(newExercise.getDescription());
e.setMuscle(newExercise.getMuscle());
return repository.save(e);
})
.orElse(null);
}
}
This is my ExerciseRepository
package com.fazla.exercise.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import com.fazla.exercise.model.Exercise;
public interface ExerciseRepository extends JpaRepository<Exercise, Long> {
}
This is the MuscleRepository
package com.fazla.exercise.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import com.fazla.exercise.model.Muscle;
public interface MuscleRepository extends JpaRepository<Muscle, Long>{
}
This is the error if I try the put request or update the exercise object
"timestamp": "2018-10-10T06:30:46.924+0000",
"status": 400,
"error": "Bad Request",
"message": "JSON parse error: Unresolved forward references for: ; nested exception is com.fasterxml.jackson.databind.deser.UnresolvedForwardReference: Unresolved forward references for: \n at [Source: (PushbackInputStream); line: 23, column: 1]Object id [1] (for `com.fazla.exercise.model.Muscle`) at [Source: (PushbackInputStream); line: 13, column: 28], Object id [1] (for `com.fazla.exercise.model.Muscle`) at [Source: (PushbackInputStream); line: 19, column: 28].",
"path": "/api/exercise/14"
The solution was, adding orphanRemoval= true on the Parent/ Muscle model
#OneToMany(mappedBy="muscle", cascade= CascadeType.ALL, orphanRemoval= true)
private List<Exercise> exercises = new ArrayList<>();
Removing the cascade= CascadeType.ALL in the child/ Exercise model
#ManyToOne
private Muscle muscle;
And for the updateExercise changing the Request by finding the muscle which the exercise belongs to and muscleRepository.findById(muscleId) and setting it in the new exercise object.
#PutMapping("/exercise/{id}")
public Exercise updateExercise(#RequestBody Exercise newExercise, #PathVariable Long id, #RequestParam Long muscleId) {
Muscle muscle = muscleRepository.findById(muscleId).orElse(null);
return repository.findById(id)
.map(//map a function which maps
e ->{
e.setName(newExercise.getName());
e.setDescription(newExercise.getDescription());
e.setMuscle(muscle);
return repository.save(e);
})
.orElse(null);
}
on your Exercise you have
#ManyToOne(cascade = CascadeType.ALL)
#JoinColumn(name="muscle_id")
private Muscle muscle;
and on your Musce you have
#OneToMany(cascade= CascadeType.ALL)
private List<Exercise> exercises = new ArrayList<>();
Cascade.ALL propagates all actions on your Object and if you delete a Excercise, DELETE is propagated to all referenced objects
Bacause you just want to propagate UPDATES replace
cascade = CascadeType.ALL
with
cascade = CascadeType.SAVE_UPDATE

A bean of type 'org.hibernate.SessionFactory' that could not be found

I am new to Java web developing and I am having a lot of trouble working with Hibernate. I looked at a lot of examples online on how to do this and so far I don't have any luck getting any of it to work. I notice some pattern they use online, a lot of them go like bellow.
#Autowired
private SessionFactory sessionFactory;
Session session = sessionFactory.getCurrentSession();
session.beginTransaction();
// do something with session
session.getTransaction().commit();
However, whenever I try to do that in my project, I got an error saying
Field sessionFactory in com.bT.practice.WebMySQLAspects.dao.StudentDAOImpl required a bean of type 'org.hibernate.SessionFactory' that could not be found.
I am really confused about this and I couldn't find a good example on hibernate website on how to do this. I use http://start.spring.io/ to bootstrap my app. Bellow is my code.
ENTITY
package com.bT.practice.WebMySQLAspects.entity;
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
#Table(name="student")
public class Student {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name="id")
private int id;
#Column(name="first_name")
private String firstName;
#Column(name="last_name")
private String lastName;
#Column(name="email")
private String email;
public Student() {
}
public Student(String firstName, String lastName, String email) {
this.firstName = firstName;
this.lastName = lastName;
this.email = email;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
#Override
public String toString() {
return "Student [id=" + id + ", firstName=" + firstName + ", lastName=" + lastName + ", email=" + email + "]";
}
}
DAO IMPLEMENTATION
package com.bT.practice.WebMySQLAspects.dao;
import java.util.List;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import com.bT.practice.WebMySQLAspects.entity.Student;
#Repository
public class StudentDAOImpl implements StudentDAO {
#Autowired
private SessionFactory sessionFactory;
#Override
public List<Student> getStudents() {
Session session = sessionFactory.getCurrentSession();
session.beginTransaction();
List<Student> students = session.createQuery("from Student order by lastName").list();
session.getTransaction().commit();
return students;
}
}
SERVICE IMPLEMENTATION
package com.bT.practice.WebMySQLAspects.service;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.bT.practice.WebMySQLAspects.dao.StudentDAO;
import com.bT.practice.WebMySQLAspects.entity.Student;
#Service
public class StudentServiceImpl implements StudentService {
#Autowired
private StudentDAO studentDAO;
#Override
#Transactional
public List<Student> getStudents() {
return studentDAO.getStudents();
}
}
CONTROLLER
package com.bT.practice.WebMySQLAspects.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
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.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.bT.practice.WebMySQLAspects.entity.Student;
import com.bT.practice.WebMySQLAspects.service.StudentService;
#RestController
#RequestMapping("/api")
public class StudentController {
#Autowired
private StudentService studentService;
#GetMapping("/students/show")
public List<Student> getStudents() {
List<Student> students = studentService.getStudents();
return students;
}
}
application.properties
spring.datasource.driverClssName=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/hb_student_tracker?useSSL=false
spring.datasource.username=username
spring.datasource.password=password
Since hibernate has existed for nearly two decades now, many tutorials are horribly outdated. You'll have a far easier time if you use tutorials released in the last few years.
Originally hibernate could be accessed only in a hibernate specific way, using Sessions obtained from a SessionFactory. In 2006, the Java Persistence API standard created a general way of accessing object relational mappers in Java through EntityManagers obtained from an EntityManagerFactory. Its design was heavily influenced by the Hibernate team, and became the preferred way to access hibernate with the release of Hibernate 3.2 in the fall of 2006.
That is, the tutorials you found have been obsolete for over a decade. To see how it's done now, check out
the Spring Team's tutorial Accessing Data With JPA
and the comprehensive documentation of Spring Data JPA

Building controller using Spring RestController and Jackson give me HTTP Stats 406

I'm building a rest controller using Spring to handle request and Jackson to serialize data.However I followed tutorial online but I end up getting an error.
HTTP Status 406 -
type Status report
message
description The resource identified by this request is only capable of generating responses with characteristics not acceptable according to the request "accept" headers.
After Google for a while, I realized that it is because I don't have "application/json" as my "Accept" header in my request:
So I use a tool called Postman to manually add this "Accept" header in the request, send the request again, but still getting the same error:
I'm so confused, I've already included "application/json" as one of accepted data-type, why I still have this data-unsupported error? FYI, here is my Rest Controller class:
package mywebapp.controller;
import java.io.IOException;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import mywebapp.dao.model.interfaces.PetDao;
import mywebapp.model.Pet;
#RestController
#RequestMapping(value = "petJson.htm")
public class PetControllerAjax {
private static final Logger LOG = LoggerFactory.getLogger(PetController.class);
public static Logger getLog() {
return LOG;
}
#Autowired
#Qualifier("PetDaoJpaImpl")
private PetDao petDao;
public PetDao getPetDao() {
return petDao;
}
public void setPetDao(PetDao petDao) {
this.petDao = petDao;
}
#RequestMapping(method = RequestMethod.GET)
public List<Pet> getAllPets() throws IOException {
getLog().info("Rest Controller activating........");
List<Pet> petList = getPetDao().getAllPets();
return petList;
}
}
And here is my Pet entity class:
package mywebapp.model;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.Date;
import java.util.Set;
#Entity
#Table(name = "pet")
public class Pet {
private int petId;
private String name;
private String owner;
private String species;
private String sex;
private Date birth;
private Date death;
private Set<Toy> toys;
#Id
#Column(name = "pet_id")
#GeneratedValue
#JsonProperty(value="pet_id",required=true)
public int getId() {
return petId;
}
public void setId(int id) {
this.petId = id;
}
#JsonProperty(value="pet_name",required=true)
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getOwner() {
return owner;
}
public void setOwner(String owner) {
this.owner = owner;
}
public String getSpecies() {
return species;
}
public void setSpecies(String species) {
this.species = species;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public Date getBirth() {
return birth;
}
public void setBirth(Date birth) {
this.birth = birth;
}
public Date getDeath() {
return death;
}
public void setDeath(Date death) {
this.death = death;
}
#OneToMany(cascade=CascadeType.ALL,fetch=FetchType.EAGER,targetEntity=Toy.class, mappedBy="pet")
public Set<Toy> getToys() {
return toys;
}
public void setToys(Set<Toy> toys) {
this.toys = toys;
}
}
Anyone knows what's going on here? Any hint will be appreciated, lots of thanks in advance!
Jackson 2.7 is not supported by Spring 4.2 - it will be in 4.3+.
Check out the library requirements for Spring on the Spring wiki and see SPR-13728 and SPR-13483.

Categories

Resources