Cannot Resolve Repository Metadata for Customers - java

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")

Related

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

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..

UnsatisfiedDependencyException: Error creating bean with name 'procjectController': Unsatisfied dependency expressed through field

I am building simple ManyToOne relationship using spring JAP. i get UnsatisfiedDependencyException Error with bean name Unsatisfied dependency expressed through field
UnsatisfiedDependencyException: Error creating bean with name 'procjectController': Unsatisfied
Here is my file.
project.java
package com.ganesh.dto;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import com.fasterxml.jackson.annotation.JsonIgnore;
#Entity
public class Project {
#Id
private int projectId;
private String projectName;
//Relation establish
#ManyToOne(
fetch = FetchType.LAZY,
optional = false
)
#JoinColumn(
name = "employee_id",
nullable = false
)
#JsonIgnore
private Employee employee;
public Project() {
}
public Project(int projectId, String projectName, int eId) {
super();
this.projectId = projectId;
this.projectName = projectName;
//Adding employee
this.employee = new Employee(eId,"","");
}
public int getProjectId() {
return projectId;
}
public void setProjectId(int projectId) {
this.projectId = projectId;
}
public String getProjectName() {
return projectName;
}
public void setProjectName(String projectName) {
this.projectName = projectName;
}
//Adding getter and setters Employee reference
public Employee getEmployee() {
return employee;
}
public void setEmployee(Employee employee) {
this.employee = employee;
}
}
ProjectDao.java
package com.ganesh.dao;
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import com.ganesh.dto.Project;
#Repository
public interface ProjectDao extends JpaRepository<Project, Integer> {
List<Project> findEmployeeById(int eId);
}
ImpProjectService.java
package com.ganesh.service;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ganesh.dao.*;
import com.ganesh.dto.Project;
#Service
public class ImpProjectService implements ProjectService {
#Autowired
private ProjectDao projectDao;
#Override
public List<Project> getProjectList(int eId) {
System.out.println("in Dao class employee id"+ eId);
return projectDao.findEmployeeById(eId);
}
#Override
public Project getProjectById(int id) {
return projectDao.getOne(id);
}
#Override
public void addProject(Project project) {
projectDao.save(project);
}
#Override
public void updateProject(Project project) {
projectDao.save(project);
}
#Override
public void deleteProjectById(int id) {
projectDao.deleteById(id);
}
#Override
public List<Project> getAllProject() {
return projectDao.findAll();
}
}
ProcjectController.java
package com.ganesh.controller;
import java.util.List;
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 com.ganesh.dto.*;
import com.ganesh.service.*;
#RestController
public class ProcjectController {
#Autowired
private ImpProjectService projectService;
#RequestMapping("/projects")
public List<Project> getProjectList(){
return projectService.getAllProject();
}
#RequestMapping("/employees/{eId}/projects")
public List<Project> getAllProjects(#PathVariable int eId){
System.out.println("In Project Controller");
List<Project> projList = projectService.getProjectList(eId);
System.out.println(projList);
return projList;
}
#RequestMapping("/employees/{eId}/projects/{id}")
public Project getProjectById(#PathVariable int id) {
return projectService.getProjectById(id);
}
#RequestMapping(method = RequestMethod.POST, value="/employees/{eId}/projects")
public void addProject(#RequestBody Project project, #PathVariable int eId) {
project.setEmployee(new Employee(eId,"",""));
projectService.addProject(project);
}
#RequestMapping(method = RequestMethod.PUT, value="/employees/{eId}/projects/{id}")
public void updateProject(#RequestBody Project project, #PathVariable int eId) {
project.setEmployee(new Employee(eId,"",""));
projectService.updateProject(project);
}
#RequestMapping(method = RequestMethod.DELETE, value="/projects/{id}")
public void deleteProjecstById(#PathVariable int id) {
projectService.deleteProjectById(id);
}
}
Note: This answer is based on insufficient data, because stack trace is not available. With correct and complete stacktrace, we might be able to provide more precise answer.
Answer:
Looks like a problem in your Dao class.
You have written
#Repository
public interface ProjectDao extends JpaRepository<Project, Integer> {
List<Project> findEmployeeById(int eId);
}
Which means you are creating a repository of type Project and trying to fire a query as findEmployeeById, It should either be findByEmployee, which accepts Employee as a parameter, or should not be there in place at all. Because the query syntax and the Template parameters do not match. So Spring will not be able to initialize the query handlers for the same.
Try changing it as below, if is satisfies your purpose.
#Repository
public interface ProjectDao extends JpaRepository {
List<Project> findAllByEmployee(Employee emp);
}
Please check the same, and correct. If it still doesn't work, please post the full stack trace, and we can help you out.

java.sql.Timestamp value; nested exception is java.sql.SQLDataException in Spring-boot project

I'm building a project with spring boots, checking the status of the Internet through control, and I'm in the process of a DB connection.
I'm trying to do 'MyBatis', but there's an error.
This is a list of my directories:
MinitoringdataApplication.java
package com.smartcore.mn.springboot;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication
#MapperScan(basePackages = "com.smartcore.mn.springboot")
public class MinitoringdataApplication {
public static void main(String[] args) {
SpringApplication.run(MinitoringdataApplication.class, args);
}
}
ServletInitializer.java
package com.smartcore.mn.springboot;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
public class ServletInitializer extends SpringBootServletInitializer {
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(MinitoringdataApplication.class);
}
}
ApiController.java
package com.smartcore.mn.springboot.controller;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import com.smartcore.mn.springboot.model.Member;
import com.smartcore.mn.springboot.service.MemberService;
#RestController
public class ApiController {
#Autowired
MemberService memberService;
#GetMapping(path = "/helloWorld")
public String helloWorld() {
return LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME);
}
#GetMapping(path = "/db")
public List<Member> selectAllMember() {
List<Member> members = memberService.getAllMember();
return members;
}
}
MemberMapper.interface
package com.smartcore.mn.springboot.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Mapper;
import com.smartcore.mn.springboot.model.Member;
#Mapper
public interface MemberMapper {
Member selectMemberById(Long id);
List<Member> selectAllMember();
void insertMember(Member member);
}
Member.java
package com.smartcore.mn.springboot.model;
import java.util.Date;
import org.apache.ibatis.type.Alias;
import com.smartcore.mn.springboot.Exception.IdPasswordNotMatchingException;
import lombok.Data;
#Data
#Alias("member")
public class Member {
private Long id;
private String email;
private String password;
private String name;
private Date registerDate;
public Member(String email, String password, String name, Date registerDate) {
this.email = email;
this.password = password;
this.name = name;
this.registerDate = registerDate;
}
public void setId(Long id) {
this.id = id;
}
public Long getId() {
return id;
}
public String getEmail() {
return email;
}
public String getPassword() {
return password;
}
public String getName() {
return name;
}
public Date getRegisterDate() {
return registerDate;
}
public void changePassword(String oldPassword, String newPassword) {
if (!password.equals(oldPassword))
throw new IdPasswordNotMatchingException();
this.password = newPassword;
}
}
MemberService.java
package com.smartcore.mn.springboot.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.smartcore.mn.springboot.mapper.MemberMapper;
import com.smartcore.mn.springboot.model.Member;
#Service
#Transactional
public class MemberService {
#Autowired
MemberMapper memberMapper;
public Member getMemberById(Long id) {
return memberMapper.selectMemberById(id);
}
public List<Member> getAllMember() {
return memberMapper.selectAllMember();
}
public void addMember(Member member) {
memberMapper.insertMember(member);
}
}
application.properties
spring.datasource.url=jdbc:mysql://localhost/mydb?serverTimezone=UTC&autoReconnection=true
spring.datasource.username=mydb
spring.datasource.password=mydb
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
mybatis.type-aliases-package=com.smartcore.mn.springboot.model
logging.level.com.smartcore.mn.springboot.mapper=TRACE
MemberMapper.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.smartcore.mn.springboot.mapper.MemberMapper">
<select id="selectMemberById" resultType="member">
SELECT *
FROM MEMBER
WHERE ID = #{id}
</select>
<select id="selectAllMember" resultType="member">
SELECT *
FROM MEMBER
</select>
<insert id="insertMember">
INSERT INTO MEMBER (EMAIL, PASSWORD, NAME, REGDATE)
VALUES (#{email}, #{password}, #{name}, #{registerDate})
</insert>
</mapper>
http://localhost:8080/helloworld is works normally.
But http://localhost:8080/db have see Error
I need your solution. Thank you in advance.
my TABLE
As mentioned in our discussion in comments, MyBatis is trying to map your NAME column in result-set to the registerDate argument in the Member constructor.
Since you did not specify paramName for each fields, the order of arg elements in the constructor is error-prone.
Try mapping your result-set to your constructor with correct ordered args:
Member(String email, String password, String name, Date registerDate) should match SELECT EMAIL, PASSWORD, NAME, REGDATE FROM MEMBER
or
Member(Long id, String email, String password, String name, Date registerDate) should match SELECT * FROM MEMBER

Spring Boot REST API gives empty rows

I am new to Spring boot. I have a MYSQL table "customer" with data as shown:
Data in the table When testing the API output using Postman, there seems to be rows of empty JSON output.
API Output
Below is my code:
package com.semika.customer;
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="customer")
public class Customer {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#Column(name="first_name")
private String firstName;
#Column(name="last_name")
private String lastName;
#Column(name="address")
private String address;
public Customer() {
super();
}
}
CustomerRepository
package com.semika.customer;
import org.springframework.data.repository.CrudRepository;
public interface CustomerRepository extends CrudRepository<Customer, Long>{
}
CustomerService
package com.semika.customer;
public interface CustomerService {
public Iterable<Customer> findAll();
}
CustomerServiceImpl
package com.semika.customer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
#Service
public class CustomerServiceImpl implements CustomerService{
#Autowired
private CustomerRepository customerRepository;
public Iterable<Customer> findAll() {
return customerRepository.findAll();
}
}
CustomerController
package com.semika.customer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
#RestController
public class CustomerController {
#Autowired
private CustomerService customerService;
#RequestMapping("/customers")
#ResponseBody
public Iterable<Customer> findAll() {
Iterable<Customer> customers = customerService.findAll();
return customers;
}
}
I don't know what else I need to modify in the controller to be able to see the output with data.
At first look your code seems fine. So, I copied your code and try to run it and got an empty response just like you. After spending some time I figured out the reason why.
Use getter and setter in you customer class and recompile the code.
It will solve your problem. Also do the following changes:
1) Annotate CustomerRepository with #Repository
2) use #EnableJpaRepositories("package path") in your application's main class if your repository is not in the same or sub package.
3) use method type or #GetMapping annotation in your controller.
For your convenience I am writing your code after all the modifications:
TestDemoApplication.java
package testdemo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
#SpringBootApplication
#EnableJpaRepositories("put repository path here")
public class TestDemoApplication {
public static void main(String[] args) {
SpringApplication.run(TestDemoApplication.class, args);
}
}
CustomerServiceImpl.java
package testdemo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
#Service
public class CustomerServiceImpl implements CustomerService{
#Autowired
private CustomerRepository customerRepository;
public Iterable<Customer> findAll() {
return customerRepository.findAll();
}
}
CustomerService.java
package testdemo;
public interface CustomerService {
public Iterable<Customer> findAll();
}
CustomerRepository.java
package testdemo;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
#Repository
public interface CustomerRepository extends CrudRepository<Customer, Long>{
}
CustomerController.java
package testdemo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
#RestController
public class CustomerController {
#Autowired
private CustomerService customerService;
#GetMapping(value = "/customers")
public Iterable<Customer> findAll() {
Iterable<Customer> customers = customerService.findAll();
return customers;
}
}
Customer.java
package testdemo;
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="customer")
public class Customer {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#Column(name="first_name")
private String firstName;
#Column(name="last_name")
private String lastName;
#Column(name="address")
private String address;
public Customer() {
super();
}
public Long getId() {
return id;
}
public void setId(Long 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 getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
Also, CrudRepository returns a Iterable<> in findAll(). It is the JpaRepository which returns List<> so, no worries about it.
You may need to iterate over the dataset and add the results to a List or as Vishal stated, change your interfaces and implementations to return a List rather than an Iterable.
package com.semika.customer;
import java.util.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
#RestController
public class CustomerController {
#Autowired
private CustomerService customerService;
#RequestMapping("/customers")
#ResponseBody
public Iterable<Customer> findAll() {
List<Customer> results = new ArrayList<>();
Iterator<Customer> iter = customerService.findAll().iterator();
while (iter.hasNext()) results.add(iter.next());
return results;
}
}
In the following post, Andy states,
While a List is guaranteed to be an Iterable an Iterable may not be a List. This means that if you do cast an Iterable to a List it may fail at runtime. Even if it works, there's no guarantee that it will continue to work in the future as it could change in new versions of Spring Data JPA without breaking the interface's contract.
Instead of using a cast, you should declare your own query methods that return List.
Also noted in that post, you can use JpaRepository rather than CrudRepository because JPA will return a List rather than an Iterable as mentioned here.

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