Spring Boot JPA #Query problem how to fix - java

I need some help. I'm writing web applications using JPA. I make it with a tutorials on YouTube and other pages.
I Make a lot but i need help to view one thing from my aplication.
I have clients and also dates of appointments because it is an application for a hairdressing salon.
This is how look my aplication in InteliJ
https://i.stack.imgur.com/HlDXK.png
I want to display clients where first name is for example "Patryk"
Here is code from model.klienci
package figura.zaklad_fryzjerski_v3.model;
import javax.persistence.*;
#Entity
#Table(name = "klienci")
public class Klienci {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id_klienta")
private Integer id_klienta;
#Column(name = "imie")
private String imieKlienta;
#Column(name = "nazwisko")
private String nazwiskoKlienta;
#Column(name = "nr_telefonu_klienta")
private Integer nrTelefonuKlienta;
#Column(name = "adres_email")
private String adresEmailKlienta;
getters and setters
Here is code from repository.KlienciRepository
package figura.zaklad_fryzjerski_v3.repository;
import figura.zaklad_fryzjerski_v3.model.Klienci;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
#Repository
public interface KlienciRepository extends JpaRepository<Klienci, Integer> {
}
Here is code from service.KlienciService
package figura.zaklad_fryzjerski_v3.service.klienci;
import figura.zaklad_fryzjerski_v3.model.Klienci;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.repository.Query;
import java.util.List;
public interface KlienciService {
List<Klienci> getAllKlieci();
void saveKlienci(Klienci klienci);
Klienci getKlienciById(Integer id_klienta);
void usunKlientaById(Integer id_klienta);
Page<Klienci> findPaginated(int pageNo, int pageSize);
}
Here is code from service.KlienciServiceImpl
package figura.zaklad_fryzjerski_v3.service.klienci;
import figura.zaklad_fryzjerski_v3.model.Klienci;
import figura.zaklad_fryzjerski_v3.repository.KlienciRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Optional;
#Service
//#Transactional
public class KlienciServiceImpl implements KlienciService{
#Autowired
private KlienciRepository klienciRepository;
#Override
public List<Klienci> getAllKlieci() {
return klienciRepository.findAll();
}
#Override
public void saveKlienci(Klienci klienci){
this.klienciRepository.save(klienci);
}
#Override
public Klienci getKlienciById(Integer id_klienta) {
Optional<Klienci> optional = klienciRepository.findById(id_klienta);
Klienci klienci = null;
if(optional.isPresent()){
klienci = optional.get();
}else{
throw new RuntimeException("Klient nie znaleziony po id :: "+ id_klienta);
}
return klienci;
}
#Override
public void usunKlientaById(Integer id_klienta){
this.klienciRepository.deleteById(id_klienta);
}
#Override
public Page<Klienci> findPaginated(int pageNo, int pageSize) {
Pageable pageable = PageRequest.of(pageNo - 1,pageSize);
return this.klienciRepository.findAll(pageable);
}
}
And i also include you controler here what i use to dispaly things on pages in my application
//klient wyświetlanie listy klientów
#Autowired
public KlienciService klienciService;
#GetMapping("/klient_baza")
public String getKlient_baza(Model model){
model.addAttribute("listaKlientow",klienciService.getAllKlieci());
return findPaginated(1, model);
}
//Dodawanie klientów do bazy danych
#GetMapping("/klient_dodaj")
public String getKlient_dodaj(Model model){
Klienci klienci = new Klienci();
model.addAttribute("klienci",klienci);
return "/klient/klient_dodaj";
}
//zapisywanie klientów do bazy danych
#PostMapping("/klientZapisz")
public String saveKlient(#ModelAttribute("klienci") Klienci klienci, Model model){
klienciService.saveKlienci(klienci);
model.addAttribute("typ", "dodanie_rekordu");
model.addAttribute("sukces", "Pomyślnie dodano klienta");
return getKlient_baza(model);
}
//strona z edytowaniem klienta
#GetMapping("/klient_dodaj/{id_klienta}")
public String showFormForUpdate(#PathVariable(value = "id_klienta") Integer id_klienta, Model model) {
Klienci klienci = klienciService.getKlienciById(id_klienta);
model.addAttribute("klienci", klienci);
model.addAttribute("edycja", "true");
return "/klient/klient_dodaj";
}
//usuwanie klienta z bazy danych
#GetMapping("/usun_klienta/{id_klienta}")
public String usunKlienta(#PathVariable(value = "id_klienta")Integer id_klienta, Model model){
model.addAttribute("typ","usuniecie_rekordu");
model.addAttribute("sukces","Pomyślnie usunięto klienta");
this.klienciService.usunKlientaById(id_klienta);
return getKlient_baza(model);
}
//podział na strony
#GetMapping("/klient_baza/{pageNo}")
public String findPaginated(#PathVariable(value = "pageNo")int pageNo, Model model){
int pageSize = 10;
Page<Klienci> page = klienciService.findPaginated(pageNo,pageSize);
List<Klienci> klienciList = page.getContent();
model.addAttribute("aktualnaStrona", pageNo);
model.addAttribute("wszystkieStrony", page.getTotalPages());
model.addAttribute("total", page.getTotalElements());
model.addAttribute("listaKlientow", klienciList);
return "/klient/klient_baza";
}
How to add here QUERY METHOD do display only this clients where name is "Patryk" using #Query?

You don't really need to use a method annotated with #Query. Spring Data is "smart" enough to generate a query based on the model properties. You can just add a method declaration to your KlienciRepository interface:
List<Klienci> listKlienciByNazwiskoKlienta(String name);
Spring data will look into the Klienci model for a property called nazwiskoKlienta and build a query that does an equality check using the value passed in. If you wanted to do a wildcard query, Spring data can handle that automatically too:
List<Klienci> listKlienciByNazwiskoKlientaContaing(String name);

Put this code inside in your repository
#Repository
public interface KlienciRepository extends JpaRepository<Klienci, Integer> {
List<Klienci> findByimieKlientaIgnoreCase(String firstName);
}

Why not to use the power of Spring Data in its whole extension??
public interface KlienciRepository extends JpaRepository<Klienci, Integer> {
Klienci findByImieKlienta (String imieKlienta);
}
and later you can call this method with the String you want, in this case "Patryk".

#Repository
public interface KlienciRepository extends JpaRepository<Klienci, Integer> {
#Query(SELECT * from klienci k where k.imieKlienta like "?1%")
List<klienci> findbyfirstname(String firstname);
}

package figura.zaklad_fryzjerski_v3.repository;
import figura.zaklad_fryzjerski_v3.model.Klienci;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
#Repository
public interface KlienciRepository extends JpaRepository<Klienci, Integer> {
#Query(value="SELECT * FROM klienci WHERE imie=?1",nativeQuery = true)
public List<Klienci> getClientsByName(String clientName);
}

Related

ReactiveCosmosRepository delete functions not working

I'm building a Spring Boot app using CosmosDB as my database. All functions work (creating an item, updating one, get all, get by id,...), apart from delete functions. They don't do anything and since their output is void, it doesn't give me any logs either.
The DAO class:
package projects.trashcanapplication.trashcan.dao;
import com.azure.spring.data.cosmos.core.mapping.Container;
import com.azure.spring.data.cosmos.core.mapping.GeneratedValue;
import com.azure.spring.data.cosmos.core.mapping.PartitionKey;
import org.springframework.data.annotation.Id;
import projects.trashcanapplication.trashcan.models.Address;
import projects.trashcanapplication.trashcan.models.FillStatus;
#Container(containerName = "trashcanData")
public class TrashcanDao{
#GeneratedValue
private String attachments;
private FillStatus fillStatus;
#GeneratedValue
private String rid;
private Address address;
#Id
#PartitionKey
#GeneratedValue
private String id;
#GeneratedValue
private String self;
#GeneratedValue
private String etag;
#GeneratedValue
private int ts;
public TrashcanDao(Address address, FillStatus fillStatus) {
this.fillStatus = fillStatus;
this.address = address;
}
public String getAttachments(){
return attachments;
}
public FillStatus getFillStatus(){
return fillStatus;
}
public String getRid(){
return rid;
}
public Address getAddress(){
return address;
}
public String getId(){
return id;
}
public String getSelf(){
return self;
}
public String getEtag(){
return etag;
}
public int getTs(){
return ts;
}
}
The repository
package projects.trashcanapplication.trashcan.repositories;
import com.azure.spring.data.cosmos.repository.ReactiveCosmosRepository;
import projects.trashcanapplication.trashcan.dao.TrashcanDao;
public interface TrashcanRepository extends ReactiveCosmosRepository<TrashcanDao, String> {
}
The service calling the repository
package projects.trashcanapplication.trashcan.services;
import com.azure.cosmos.models.PartitionKey;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import projects.trashcanapplication.trashcan.dao.TrashcanDao;
import projects.trashcanapplication.trashcan.models.Trashcan;
import projects.trashcanapplication.trashcan.repositories.TrashcanRepository;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
#Slf4j
#Service
#AllArgsConstructor
public class TrashcanServiceImpl implements TrashcanService {
private final TrashcanRepository trashcanRepository;
private final TrashcanMapper trashcanMapper;
public Flux<Trashcan> getAllTrashcans() {
return trashcanRepository.findAll().map(trashcanMapper::fromDaoToTrashcan);
}
public Mono<Trashcan> getTrashcanById(String id) {
return trashcanRepository.findById(id).map(trashcanMapper::fromDaoToTrashcan);
}
public String createTrashcan(Trashcan trashcan) {
TrashcanDao saveTrashcan = trashcanMapper.fromTrashcanToDao(trashcan);
trashcanRepository.save(saveTrashcan).subscribe();
return saveTrashcan.getId();
}
public void deleteTrashcan(String id) {
trashcanRepository.deleteById(id, new PartitionKey(id));
log.info(String.format("Deleted trashcan %s", id));
}
}
I have a dataloader temporarily set up to populate my DB with an item upon running the app. The deleteAll() function doesn't work here either.
package projects.trashcanapplication.trashcan.services;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import projects.trashcanapplication.trashcan.dao.TrashcanDao;
import projects.trashcanapplication.trashcan.models.Address;
import projects.trashcanapplication.trashcan.models.FillStatus;
import projects.trashcanapplication.trashcan.repositories.TrashcanRepository;
import javax.annotation.PostConstruct;
#Slf4j
#Component
#AllArgsConstructor
public class DataLoader {
private final TrashcanRepository trashcanRepository;
#PostConstruct
void loadData() {
Address address1 = new Address("Begijnendijk", "3130", "Liersesteenweg", "181");
trashcanRepository.deleteAll();
trashcanRepository.save(new TrashcanDao(address1, FillStatus.EMPTY))
.flatMap(trashcanRepository::save)
.thenMany(trashcanRepository.findAll())
.subscribe(trashcan -> log.info(trashcan.getId().toString()))
;
}
}
You're not subscribing anywhere, so the reactive stream isn't executed.
You could solve that by subscribing manually:
trashcanRepository.deleteAll().subscribe()
However, this is not a good practice, and certainly not in your DataLoader as you can't guarantee the order in which the save/delete-logic is executed (maybe the TrashcanDao is saved before you delete everything).
To solve this, you should create a proper reactive stream:
trashcanRepository
.deleteAll()
.then(trashcanRepository.save(new TrashcanDao(address1, FillStatus.EMPTY)))
.thenMany(trashcanRepository.findAll())
// Your previous subscribe() shouldn't compile since it should contain List<TrashcanDao>
.subscribe(trashcans -> log.info(trashcans.size()));

How can I reach database as json value when i request on my local browser?

Note: This is a project which has a connection with database on other tables. I just made a new table, but i must have something wrong in my codes, because i cant get what i want.
I have a City table, and this table has 3 columns, named id, name, city_id. And i imported a csv file, so when i query, I can see some data.
I wrote Entity, Repository, Controller, and Service, in Java on Eclipse
What should I do? For example, when i search like localhost:8181/mfc/city/getAllCities that should give me all the cities as json
Could you tell me what i should add?
City.java
package com.mfc.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="city")
public class City{
#Id
#Column(name="id")
#GeneratedValue(strategy=GenerationType.IDENTITY)
int id;
#Column(name="city_name")
String cityName;
#Column(name="city_id")
int cityId;
public City() {
super();
}
public City(int id, String cityName, int cityId) {
super();
this.id = id;
this.cityName = cityName;
this.cityId = cityId;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getCityName() {
return cityName;
}
public void setCityName(String cityName) {
this.cityName = cityName;
}
public int getCityId() {
return cityId;
}
public void setCityId(int cityId) {
this.cityId = cityId;
}
}
CityController.java
package com.mfc.admin.controller;
import java.util.List;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.mfc.admin.service.CityService;
import com.mfc.entity.City;
#RestController
#RequestMapping("/city")
public class CityController {
private static final Logger logger = LogManager.getLogger(CityController.class);
#Autowired
CityService cityService;
#RequestMapping(value="/getAllCities", method=RequestMethod.GET, headers = "Accept=application/json")
public List getCities() {
logger.trace("CityController: getAllCities begins");
List listOfCities = cityService.getAllCities();
logger.trace("CityController: getAllCities ends");
return listOfCities;
}
#RequestMapping(value="/getCity/{id}", method=RequestMethod.GET, headers = "Accept=application/json")
public City getCityById(#PathVariable int id) {
return cityService.getCity(id);
}
}
CityService.java
package com.mfc.admin.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.mfc.entity.City;
import com.mfc.repository.CityRepository;
#Service("cityService")
public class CityService {
#Autowired
CityRepository cityDTO;
#Transactional
public List getAllCities() {
return cityDTO.getAllCities();
}
#Transactional
public City getCity(int id) {
return cityDTO.getCity(id); // getCity is red here, there is mistake i guess
}
}
CityRepository.java
package com.mfc.repository;
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import com.mfc.entity.City;
public interface CityRepository extends JpaRepository<City, Integer>{
List getAllCities();
City getCity();
}
In the CityService you call the CityRepository like this
return cityDTO.getCity(id); // getCity is red here, there is mistake i guess
But no such method is defined in the CityRepository. Try using this line return cityDTO.findById(id).get();
You can't see the method findById(Integer id) in the CityRepository, but it is there, because the CityRepository extends JpaRepository<City, Integer>. Find some Spring Data tutorial to know what's really going on in here, long story short the Spring Data is able to generate a lot of standard methods for you.
The method cityDTO.findById(id) returns Optional<City>, not City. To get the instance of City, just add '.get()' method, as it is in the example. It should work for you if city exists in the database. For proper work with Optional find some tutorial. It is a wrapper of an object that may or may not be present, detailed explanation is out of the scope of this answer.
maybe you can try to set up message converter manualy, google MappingJackson2HttpMessageConverter and you'll know what to do.

Spring JPA "And" Methods and Not Null

Been having ridiculous trouble with using the AND in the CrudReposity. All I want to do it find if two things are Not Null and display them.
public interface StudentRepository extends CrudRepository<Student, Integer>{
List<Student> findByItemAIsNotNullAndItemBIsNotNull();
}
When I run this, it seems to be running the AND as an OR (I tried both), so it's showing things that all null in one of them.
Any Help will be appreciated
You Code is correct may be problem in other section. Otherwise you can see this code. It may help you. Here I skipped service layer though its for only test.
package com.example.stack;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
#Entity
public class Data{
#Id
#GeneratedValue
Integer id;
String itemA;
String itemB;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getItemA() {
return itemA;
}
public void setItemA(String itemA) {
this.itemA = itemA;
}
public String getItemB() {
return itemB;
}
public void setItemB(String itemB) {
this.itemB = itemB;
}
}
Repository Class
package com.example.stack;
import java.util.List;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
public interface TestRepository extends CrudRepository<Data, Integer>{
List<Data> findByItemAIsNotNullAndItemBIsNotNull();
}
Controller CLass
package com.example.stack;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
#RestController
#RequestMapping(value = "/test")
public class TestController {
#Autowired
TestRepository repo;
#GetMapping
public List<Data> getTest()
{
return (List<Data>) repo.findByItemAIsNotNullAndItemBIsNotNull();
}
}
Database :
Response :

Best way to implement 20 #RestController's in spring-framework without repeating yourself (DRY) [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 7 years ago.
Improve this question
After implementing about 20 rest controllers & services, I found myself that A LOT of my code was repeated, so I came up with this contraption.
CrudController.java
package app.controllers;
import org.springframework.data.repository.CrudRepository;
import org.springframework.ui.ModelMap;
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 app.models.Model;
import app.services.CrudService;
#RestController
public abstract class CrudController<M extends Model, S extends CrudService<M, ? extends CrudRepository<M,Long>>> {
S service;
public abstract void setService(S service);
public abstract Boolean isAuthorized(Long entityId, S service);
#RequestMapping(value="/create", method = RequestMethod.POST)
public M create(M object) {
if(isAuthorized(object.getId(), service)) {
return service.save(object);
}
logUnauthorizedAccess();
return null;
}
#RequestMapping(value="/update", method = RequestMethod.POST)
public M update(M object) {
if(isAuthorized(object.getId(), service)) {
return service.update(object);
}
logUnauthorizedAccess();
return null;
}
#RequestMapping(value="/delete", method = RequestMethod.POST)
public Boolean delete(Long id) {
if(isAuthorized(id, service)) {
return service.delete(id);
}
logUnauthorizedAccess();
return null;
}
#RequestMapping(value="/get", method = RequestMethod.GET)
public #ResponseBody M get(Long id) {
if(isAuthorized(id, service)) {
return service.get(id);
}
logUnauthorizedAccess();
return null;
}
#RequestMapping(value="/json", method = RequestMethod.GET)
public #ResponseBody Iterable<M> json(ModelMap map) {
return service.getAll();
}
private void logUnauthorizedAccess() {
System.out.println("!!UN-AUTHORIZED ACCESS DETECTED!!");
}
}
CrudService.java
package app.services;
import org.springframework.data.repository.CrudRepository;
public abstract class CrudService<M extends app.models.Model, R extends CrudRepository<M, Long>> {
R repo;
public abstract void setRepo(R repo);
/**
* Define the parameters that you want to save to the DB when calling the update() method
* #param from source object
* #param to DB object that gets saves, "return to" in this method
* #return
*/
public abstract M copy(M from, M to);
public Iterable<M> getAll() {
return this.repo.findAll();
}
/**
* Mainly used to create a new entity
* however, can also be used to save something without using the
* update() method.
* #param model
* #return saved entity model
*/
public M save(M model) {
return this.repo.save(model);
}
public M get(Long id) {
return this.repo.findOne(id);
}
public M update(M model) {
M updated = this.repo.findOne(model.getId());
updated = copy(model, updated);
return this.repo.save(updated);
}
public Boolean delete(Long id) {
this.repo.delete(id);
return true;
}
}
Model.java
package app.models;
import java.sql.Timestamp;
import java.util.Date;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.MappedSuperclass;
import javax.persistence.PrePersist;
import javax.persistence.Version;
#MappedSuperclass
public abstract class Model {
#GeneratedValue
#Id
private Long id;
private Date dateCreated;
#Version
private Timestamp dateModified;
#PrePersist
void createdAt() {
this.setDateCreated(new Date());
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Date getDateCreated() {
return dateCreated;
}
public void setDateCreated(Date dateCreated) {
this.dateCreated = dateCreated;
}
public Timestamp getDateModified() {
return dateModified;
}
public void setDateModified(Timestamp dateModified) {
this.dateModified = dateModified;
}
}
Now all my controllers look like the following while giving me.
/create /get /update /delete /json
package app.controllers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import app.models.Sample;
import app.services.SampleService;
#RestController
#RequestMapping("/sample")
public class SampleController extends CrudController<Sample, SampleService> {
#Autowired
#Override
public void setService(SampleService service) {
this.service = service;
}
#Override
public Boolean isAuthorized(Long entityId, SampleService service) {
return true;
}
}
https://github.com/ddalcu/spring-starter/commit/27fb2a0719c4780d7cf648852d93b8fd3d8759c8
What do you guys think , good bad , better way to do it ?
You should have a look at Spring Data REST.
Spring is able to handle generics:
You dont really need to subclass the CrudController for each Model As long as the implementation inside does not change.
You can work with one controller that uses a PathVariable for the class for example.
Then you have the same possibility with the CrudService and Dao too.
If you see now that for some entities you need special treatment within this controller (or service, dao) you have at least two ways that I know of:
create a complete new route for this entity type with controller, service and dao.
do not simply use the crudservice inside the crudcontroller but autowire a list (or map) and lookup the correct service to continue the route.
This forking in the second or third layer depends mostly on where you need to have special possibilities.
I have seen both approaches and currently i use a mix of this myself in spring projects.
As the dispatcher servlet is ordering requestmappings according to how many variables you have it is easy to create a more concrete mapping by simply hardcode the part with the pathvariable for a specialised controller.

JPA, Spring web - how to "find" non-existent record in database

I have web written in Spring. I use Hibernate for JPA. I need to find entity in database, I get ID from user.
Problem is if ID is not in database - I get a NullPointerException.
Now I have:
People p;
try {
p = peopleManager.findById(id);
if (p != null) {
model.addAttribute("message", "user exist, do any action");
} else {
model.addAttribute("message", "user NOT exist");
}
} catch (NullPointerException e) {
model.addAttribute("message", "user NOT exist");
}
but it looks terrible. How can I do it right?
There is complete example code:
package com.example.test.entity;
import javax.persistence.Column;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
public class People {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private int id;
#Column(name="name")
private String name;
#Column(name="age")
private int age;
}
/* ---------------------------------------------------- */
package com.example.test.dao;
import java.util.List;
import com.example.test.entity.People;
public interface PeopleDao {
public void save(People people);
public void delete(People people);
public void update(People people);
public List<People> findAll();
public People findById(int id);
}
/* ---------------------------------------------------- */
package com.example.test.dao;
import java.util.List;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import com.example.test.entity.People;
#Repository
public class PeopleDaoImpl implements PeopleDao {
#Autowired
private SessionFactory sessionFactory;
#Override
public void save(People people) {
this.sessionFactory.getCurrentSession().save(people);
}
#Override
public void delete(People people) {
this.sessionFactory.getCurrentSession().delete(people);
}
#Override
public void update(People people) {
this.sessionFactory.getCurrentSession().update(people);
}
#Override
public List<People> findAll() {
return this.sessionFactory.getCurrentSession().createQuery("from People ORDER BY age").list();
}
#Override
public People findById(int id) {
return (People) this.sessionFactory.getCurrentSession().get(People.class, id);
}
}
/* ---------------------------------------------------- */
package com.example.test.service;
import java.util.List;
import com.example.test.entity.People;
public interface PeopleManager {
public void save(People people);
public void delete(People people);
public void update(People people);
public List<People> findAll();
public People findById(int id);
}
/* ---------------------------------------------------- */
package com.example.test.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.example.test.dao.PeopleDao;
import com.example.test.entity.People;
#Service
#Transactional
public class PeopleManagerImpl implements PeopleManager {
#Autowired
private PeopleDao peopleDao;
#Override
public void save(People people) {
peopleDao.save(people);
}
#Override
public void delete(People people) {
peopleDao.delete(people);
}
#Override
public void update(People people) {
peopleDao.update(people);
}
#Override
public List<People> findAll() {
return peopleDao.findAll();
}
#Override
public People findById(int id) {
return peopleDao.findById(id);
}
/* ---------------------------------------------------- */
package com.example.test.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import com.example.test.entity.People;
import com.example.test.service.PeopleManager;
#Controller
public class PeopleController {
#Autowired
private PeopleManager peopleManager;
#RequestMapping(value = "/people/{id}", method = RequestMethod.GET)
public String home(Model model, #PathVariable("id") String id) {
People p;
try {
p = peopleManager.findById(Integer.parseInt(id));
if (p != null) {
model.addAttribute("message", "user exist, do any action");
} else {
model.addAttribute("message", "user NOT exist");
}
} catch (NullPointerException e) {
model.addAttribute("message", "user NOT exist");
}
return "people";
}
}
/* ---------------------------------------------------- */
Refactor the null check out of your controller. Controllers shouldn't have any business logic in them. The correct place for this is inside your service class.
#Override
#Transactional
public People findById(int id) throws ObjectNotFoundException{
People people = null;
people = peopleDao.findById(id);
if(people == null){
throw new ObjectNotFoundException("Couldn't find a People object with id " + id);
}
return people;
}
I would write a custom exception that extends RuntimeException that is thrown if your People object is null.
This is best practice as you can reuse your ObjectNotFoundException in all your service layers. Then make all your controller methods throw Exception and investigate global error handling for controllers.
Also, it is best practice to not annotate your entire service class as #Transactional, mark the individual methods. That way if you need to add additional methods to your services you can choose if you want them to run in a transactional context.

Categories