Spring JpaSpecificationExecutor new query method NoSuchElementException - java

I'm using Spring and JpaRepository as data access layer. I have my #Repository interface as below:
#Repository
interface EventRepository extends JpaRepository<Event, Long>, JpaSpecificationExecutor<Event> {
.... some custom methods irrelevant to this post ....
}
Here's my simplified model classes:
class Event {
Long eventID;
String name;
Date time;
Zone zone;
}
class Zone {
Long zoneId;
String zoneName;
User user;
}
class User {
Long userId;
String username;
}
I'm using there JpaSpecificationExecutor to fetch database for list of Events in specific time. I'm using this method and it work correctly:
Page<T> findAll(Specification<T> spec, Pageable pageable);
But I want to add another condition to fetch entries only for specific User.
I tried to create new method like this:
Page<Event> findAllByZone_User(User user, Specification<Event> spec, Pageable pageable);
But when I call it I get in this line Exception:
java.util.NoSuchElementException: null
Is it even possible to create such method? If not - how should I proceed?

I have created a Spring boot project like yours and this is working for me. You can check my code below.....
Event.java
package com.example.model;
import java.util.Date;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToOne;
#Entity
public class Event {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private Long eventID;
private String name;
private Date time = new Date();
#OneToOne(cascade = CascadeType.ALL)
private Zone zone;
public Long getEventID() {
return eventID;
}
public void setEventID(Long eventID) {
this.eventID = eventID;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Date getTime() {
return time;
}
public void setTime(Date time) {
this.time = time;
}
public Zone getZone() {
return zone;
}
public void setZone(Zone zone) {
this.zone = zone;
}
}
Zone.java
package com.example.model;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToOne;
#Entity
public class Zone {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private Long zoneId;
private String zoneName;
#OneToOne(cascade = CascadeType.ALL)
private User user;
public Long getZoneId() {
return zoneId;
}
public void setZoneId(Long zoneId) {
this.zoneId = zoneId;
}
public String getZoneName() {
return zoneName;
}
public void setZoneName(String zoneName) {
this.zoneName = zoneName;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
User.java
package com.example.model;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
#Entity
public class User {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private Long userId;
private String username;
public Long getUserId() {
return userId;
}
public void setUserId(Long userId) {
this.userId = userId;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
}
and my repositories are
EventRepository.java
package com.example.model;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
public interface EventRepository extends JpaRepository<Event, Long>, JpaSpecificationExecutor<Event>{
Page<Event> findAllByZoneUser(User user, Pageable pageable);
}
UserRepository.java
package com.example.model;
import org.springframework.data.jpa.repository.JpaRepository;
public interface UserRepository extends JpaRepository<User, Long>{
}
I am calling repository methods directly in my controller like below
UserController.java
package com.example.model;
import java.util.HashMap;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
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;
#RestController
public class UserController {
#Autowired
EventRepository eventRepository;
#Autowired
UserRepository userRepository;
#RequestMapping(value = "/{userId}", method = RequestMethod.GET)
public Map<String, Object> updateUserDO(#PathVariable Long userId) {
Map<String, Object> map = new HashMap<>();
User user = userRepository.findOne(userId);
PageRequest pageRequest = new PageRequest(0, 10, Sort.Direction.ASC, "eventID");
map.put("user", eventRepository.findAllByZoneUser(user, pageRequest));
return map;
}
}

Related

My repository in my spring-boot application is returning null

Hey I am pretty new to using the Spring Framework and was just trying to get an application to work for practice but I am getting the following error in my stack trace:
Cannot invoke "com.gabriel.schoolapp.repository.UsersRepo.findAll()" because "this.usersRepo" is null
This is my model layer for the Users:
package com.gabriel.schoolapp.models;
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.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
#NoArgsConstructor
#AllArgsConstructor
#Getter
#Setter
#ToString
#Entity
#Table(name = "users")
public class Users {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer usersID;
#Column(nullable = false)
private String firstName;
public void FirstName(String firstName){
this.firstName = firstName;
}
#Column(nullable = false)
private String lastName;
public void ClassDesc(String lastName){
this.lastName = lastName;
}
#Column(nullable = false)
private String username;
public void Username(String username){
this.username = username;
}
}
This is my repository layer:
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import com.gabriel.schoolapp.models.Users;
#Repository
public interface UsersRepo extends JpaRepository<Users, Integer>{
Users findByUsername(String firstName);
}
And this is my service layer:
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.gabriel.schoolapp.models.Users;
import com.gabriel.schoolapp.repository.UsersRepo;
#Service
public class UsersService {
#Autowired
private UsersRepo usersRepo;
#Autowired
public UsersService(UsersRepo usersRepo){
this.usersRepo = usersRepo;
}
public UsersService(){
}
public Users createUser(Users user){
Users checkIfUserInDb = usersRepo.findByUsername(user.getFirstName());
if(checkIfUserInDb != null){
System.out.println("Username already in DB");
return null;
}
System.out.println("User is valid");
return usersRepo.save(user);
}
public List<Users> getAllUsersById(){
return this.usersRepo.findAll();
}
}
Whenever I try to call a method from the service layer like so:
#SpringBootApplication
public class SchoolAppApplication {
public static void main(String[] args) {
SpringApplication.run(SchoolAppApplication.class, args);
UsersService serv = new UsersService();
serv.getAllUsersById();
}
}
It returns with the aforementioned error (this.usersRepo is null)
Any help would be greatly appreciated thank you!!
The UserService you created is not managed by Spring, hence the repo is not autowired. You need a few things:
implement CommandLineRunner in SchoolAppApplication
Autowire your service in SchoolAppApplication
Override method run in SchoolAppApplication and run your service there:
#Override
public void run(String... args) {
serv.getAllUsersById();
}

How to create a JPA repository for Books, Clients, Orders

I am trying to create 3 JPA repositories with 3 according services, but I don't even know how to start. Id appreciate if any of u takes a loot at this.
The book DTO
package com.mile.pc.java8.book_api_jpa.DTO;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
#Entity
#Table(name = "books")
public class Book {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private Long id;
private String name;
private String type;
private boolean available;
protected Book() {}
public Book(String name, String type, boolean available) {
super();
this.name = name;
this.type = type;
this.available = available;
}
public Long getID() {
return id;
}
public String getName() {
return name;
}
public String getType() {
return type;
}
public boolean isAvailable() {
return available;
}
#Override
public String toString() {
return "Book [id=" + id + ", name=" + name + ", type=" + type + ", available=" + available + "]";
}
}
the Order DTO:
package com.mile.pc.java8.book_api_jpa.DTO;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
#Entity
#Table(name = "orders")
public class Order {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private Integer id;
private String customerName;
protected Order() {}
public Order(Integer id, String customerName) {
super();
this.id = id;
this.customerName = customerName;
}
public int getId() {
return id;
}
public String getCustomerName() {
return customerName;
}
#Override
public String toString() {
return "Order [id=" + id + ", customerName=" + customerName + "]";
}
}
The client DTO:
package com.mile.pc.java8.book_api_jpa.DTO;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
#Entity
#Table(name = "clients")
public class Client {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private String clientEmail;
private String clientName;
protected Client() {}
public Client(String clientEmail, String clientName) {
super();
this.clientEmail = clientEmail;
this.clientName = clientName;
}
public String getClientEmail() {
return clientEmail;
}
public String getClientName() {
return clientName;
}
#Override
public String toString() {
return "Client [clientEmail=" + clientEmail + ", clientName=" + clientName + "]";
}
}
Book repo:
package com.mile.pc.java8.book_api_jpa.DTO.repo;
import java.util.ArrayList;
import java.util.List;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
import com.mile.pc.java8.book_api_jpa.DTO.Book;
#EnableJpaRepositories
#Repository
public interface BookRepository extends CrudRepository<Book, Long> {
List<Book> books = new ArrayList<>();
}
Order repo:
package com.mile.pc.java8.book_api_jpa.DTO.repo;
import java.util.ArrayList;
import java.util.List;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
import com.mile.pc.java8.book_api_jpa.DTO.Order;
#EnableJpaRepositories
#Repository
public interface OrderRepository extends CrudRepository<Order, Long> {
List<Order> orders = new ArrayList<Order>();
}
Client repo:
package com.mile.pc.java8.book_api_jpa.DTO.repo;
import java.util.HashMap;
import java.util.Map;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
import com.mile.pc.java8.book_api_jpa.DTO.Client;
#EnableJpaRepositories
#Repository
public interface ClientRepository extends CrudRepository<Client, Long> {
Map<String, Client> clients = new HashMap<String, Client>();
}
Book Service:
package com.mile.pc.java8.book_api_jpa.DTO.repo.service;
import org.springframework.stereotype.Service;
#Service
public class BookService{
}
Order service:
package com.mile.pc.java8.book_api_jpa.DTO.repo.service;
import org.springframework.stereotype.Service;
#Service
public class OrderService {
}
Client Service:
package com.mile.pc.java8.book_api_jpa.DTO.repo.service;
import org.springframework.stereotype.Service;
#Service
public class ClientService {
}
I know It's a lot to ask. But I'd appreciate it a lot...Thank you :)

Problem in Soft Deleting child entity in Spring Boot in #OneToMany relation

I have started learning Spring Boot recently.
I am trying to Soft delete the user. I want to soft delete all the Notes of the user when I soft delete the User. But my code is only soft deleting the user, not its notes.
When I am doing soft delete only on notes table, it's working fine but on User Entity, it is only deleting the user.
Notes
package com.we.springmvcboot.Model;
import java.sql.Date;
import java.util.ArrayList;
import java.util.Set;
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.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import org.hibernate.annotations.SQLDelete;
import org.hibernate.annotations.Where;
import com.fasterxml.jackson.annotation.JsonIgnore;
#Entity
#Table(name="Notes")
#Where(clause = "deleted = 'false'")//FALSE
public class Notes {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name="NotesID")
private long NotesID;
#Column(name="Title")
private String Title;
#Column(name="Message")
private String Message;
#Column(name="Date")
private String date;
#Column(name="deleted")
private String deleted="false";
#Column(name="label")
private int label=1;
#ManyToOne()
#JoinColumn(name = "UserID", nullable = false)
private User user;
public Notes() {}
public String getDeleted() {
return deleted;
}
public void setDeleted(String deleted) {
this.deleted = deleted;
}
public Notes(String title, String message, String date, User user, int label) {
super();
Title = title;
Message = message;
this.date = date;
this.user = user;
this.label=label;
}
public Notes(long notesID, String title, String message, String date, int label) {
super();
NotesID = notesID;
Title = title;
Message = message;
this.date = date;
this.label=label;
}
public int getLabel() {
return label;
}
public void setLabel(int label) {
this.label = label;
}
public long getNotesID() {
return NotesID;
}
public void setNotesID(long notesID) {
NotesID = notesID;
}
public String getTitle() {
return Title;
}
public void setTitle(String title) {
Title = title;
}
public String getMessage() {
return Message;
}
public void setMessage(String message) {
Message = message;
}
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
public void setUser(User user) {
this.user = user;
}
}
User
package com.we.springmvcboot.Model;
import java.util.ArrayList;
import java.util.Set;
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.OneToMany;
import javax.persistence.Table;
import org.hibernate.annotations.Where;
import antlr.collections.List;
#Entity
#Table(name="User")
#Where(clause = "deleted = 'false'")//FALSE
public class User {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private long UserID;
#Column(name="emailid")
private String emailID;
#Column(name="deleted")
private String deleted="false";
#OneToMany(mappedBy="user", fetch = FetchType.EAGER,cascade=CascadeType.ALL, orphanRemoval=true)
private Set<Notes> usernotes;
public User() {}
public User(String emailID) {
super();
this.emailID = emailID;
}
public long getUserID() {
return UserID;
}
public void setUserID(long userID) {
UserID = userID;
}
public String getemailID() {
return emailID;
}
public void setemailID(String emailID) {
emailID = emailID;
}
public Set<Notes> getUsernotes() {
return usernotes;
}
public void setUsernotes(Set<Notes> usernotes) {
this.usernotes = usernotes;
}
}
NotesRepository
package com.we.springmvcboot.Repository;
import java.sql.Date;
import java.util.List;
import javax.transaction.Transactional;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;
import com.we.springmvcboot.Model.Notes;
#Repository
public interface NotesRepository extends JpaRepository<Notes, Long> {
#Query("update Notes e set e.deleted='true' where e.NotesID=?1")
#Transactional
#Modifying
public void softDelete(long id);
}
UserRepository
package com.we.springmvcboot.Repository;
import java.sql.Date;
import java.util.List;
import javax.transaction.Transactional;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;
import com.we.springmvcboot.Model.Notes;
import com.we.springmvcboot.Model.User;
#Repository
public interface UserRepository extends JpaRepository<User, Long> {
List<User> findByEmailID(String email);
#Query("update User e set e.deleted='true', where e.UserID=?1")
#Transactional
#Modifying
public void softDelete(long id);
}
TodoService
package com.we.springmvcboot.Service;
import com.we.springmvcboot.Model.*;
import com.we.springmvcboot.exception.*;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestBody;
import com.we.springmvcboot.Repository.NotesRepository;
import com.we.springmvcboot.Repository.UserRepository;
#Service
public class TodoService {
#Autowired
UserRepository userrepo;
#Autowired
NotesRepository notesrepo;
public Object deleteUser(Map<String, Object> input) {
long userID;
userID = ((Number) input.get("userID")).longValue();
userrepo.softDelete(userID);
return null;
}
}
I would suggest that you read this post for the simplest approach to soft delete. You should arrive at sth like the following:
#SQLDelete("UPDATE User SET deleted = TRUE WHERE id = ?")
#Where(clause = "deleted = FALSE")
public class User {
#OneToMany(mappedBy = "user", fetch = EAGER, cascade=ALL, orphanRemoval = true)
private Set<Notes> usernotes;
...
}
#SQLDelete("UPDATE Note SET deleted = TRUE WHERE id = ?")
#Where(clause = "deleted = FALSE")
public class Note {...}
The above will work if you use the following code to delete a User:
public Object deleteUser(Map<String, Object> input) {
long userID;
userID = ((Number) input.get("userID")).longValue();
User user = userrepo.deleteById(userID);
return null;
}
If you want to keep using the custom query, though, you still need to call a separate query to delete Notes by userId, because Cascade.REMOVE will not be triggered in this case. In other words, you'll want a method like:
public interface NotesRepository extends JpaRepository<Notes, Long> {
#Query("UPDATE Notes n SET n.deleted = TRUE WHERE n.user.id = :id")
public void deleteByUserId(long id);
}
which you then call from deleteUser:
long userID;
userID = ((Number) input.get("userID")).longValue();
userrepo.softDelete(userID);
noteRepo.deleteByUserId(userID);
return null;

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

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.

Categories

Resources