I am new to Spring. When I'm trying to view localhost:8080/persons, I am getting an error
java.lang.NullPointerException: null
at by.bsuir.task.service.PersonServiceImpl.listPersons(PersonServiceImpl.java:32) ~[classes/:na]
at by.bsuir.task.controller.PersonController.listPersons(PersonController.java:31) ~[classes/:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:564) ~[na:na]
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:209) ~[spring-web-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at ...
I think problem is in PersonDAOImpl, method listPersons(), session getting NPE. But I'm not sure.
My project below:
PersonServiceImpl
package by.bsuir.task.service;
import java.util.List;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import by.bsuir.task.dao.PersonDAO;
import by.bsuir.task.model.Person;
"personService"
public class PersonServiceImpl implements PersonService {
private PersonDAO personDAO;
public void setPersonDAO(PersonDAO personDAO) {
this.personDAO = personDAO;
}
#Transactional
public void addPerson(Person p) {
this.personDAO.addPerson(p);
}
#Transactional
public void updatePerson(Person p) {
this.personDAO.updatePerson(p);
}
#Transactional
public List<Person> listPersons() {
return this.personDAO.listPersons();
}
#Transactional
public Person getPersonById(int id) {
return this.personDAO.getPersonById(id);
}
#Transactional
public void removePerson(int id) {
this.personDAO.removePerson(id);
}
}
PersonDAOImpl
package by.bsuir.task.dao;
import java.util.List;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Repository;
import by.bsuir.task.model.Person;
#Repository
public class PersonDAOImpl implements PersonDAO {
private static final Logger logger = LoggerFactory.getLogger(PersonDAOImpl.class);
private SessionFactory sessionFactory;
public void setSessionFactory(SessionFactory sf){
this.sessionFactory = sf;
}
public void addPerson(Person p) {
Session session = this.sessionFactory.getCurrentSession();
session.persist(p);
logger.info("Person saved successfully, Person Details="+p);
}
public void updatePerson(Person p) {
Session session = this.sessionFactory.getCurrentSession();
session.update(p);
logger.info("Person updated successfully, Person Details="+p);
}
"unchecked"
public List<Person> listPersons() {
Session session = this.sessionFactory.getCurrentSession();
List<Person> personsList = session.createQuery("from Person").list();
for(Person p : personsList){
logger.info("Person List::"+p);
}
return personsList;
}
public Person getPersonById(int id) {
Session session = this.sessionFactory.getCurrentSession();
Person p = (Person) session.load(Person.class, new Integer(id));
logger.info("Person loaded successfully, Person details="+p);
return p;
}
public void removePerson(int id) {
Session session = this.sessionFactory.getCurrentSession();
Person p = (Person) session.load(Person.class, new Integer(id));
if(null != p){
session.delete(p);
}
logger.info("Person deleted successfully, person details="+p);
}
}
PersonController
package by.bsuir.task.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import by.bsuir.task.model.Person;
import by.bsuir.task.service.PersonService;
#Controller
public class PersonController {
#Autowired
private PersonService personService;
required=true
#Qualifier(value = "personService")
public void setPersonService(PersonService ps){
this.personService = ps;
}
value = "/persons", method = RequestMethod.GET
public String listPersons(Model model) {
List<Person> listOfUsers = this.personService.listPersons();
model.addAttribute("person", new Person());
model.addAttribute("listPersons", listOfUsers);
return "person";
}
//For add and update person both
value= "/person/add", method = RequestMethod.POST
public String addPerson(#ModelAttribute("person") Person p){
if(p.getId() == 0){
//new person, add it
this.personService.addPerson(p);
}else{
//existing person, call update
this.personService.updatePerson(p);
}
return "redirect:/persons";
}
"/remove/{id}"
public String removePerson(#PathVariable("id") int id){
this.personService.removePerson(id);
return "redirect:/persons";
}
"/edit/{id}"
public String editPerson(#PathVariable("id") int id, Model model){
model.addAttribute("person", this.personService.getPersonById(id));
model.addAttribute("listPersons", this.personService.listPersons());
return "person";
}
}
Cannot seem to find what my problem is, I'm just learning about Spring\Hibernate
You are missing some code in your question.
For the class PersonServiceImpl, the code should be as follows:
#Service("personService")
public class PersonServiceImpl implements PersonService {
#Autowired
private PersonDAO personDAO;
// Some other code
}
Add #Autowired annotation to the PersonDAO class without doing so will result in NullPointerException as you did not create any object for that class, annotating it with #Autowired will tell the Spring where an injection needs to occur.
Related
I finished creating a simple Spring-boot project in which I can enter users and through the Get command it returns me the name (from a list of identical names) with the oldest entry date. Unfortunately, every time I ask for Get it returns this ERROR:
D:\>curl -G localhost:8080/demo/first?=Biagio
{"timestamp":"2020-10-04T22:46:35.996+00:00","status":404,"error":"Not Found","message":"","path":"/demo/first"}
And to each of my POST / Add requests like this ERROR:
D:\>curl localhost:8080/demo/add -d name=Giovanni -d email=giovanni#gmail.com -d surname=Jackie
{"timestamp":"2020-10-04T22:40:51.928+00:00","status":404,"error":"Not Found","message":"","path":"/demo/add"}
Below I enter the interested parties of my project to try to get something out of it, because I have been stuck for days now
AccessingDataMysqlApplication.java
package com.example.accessingdatamysql;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.context.annotation.ComponentScan;
#SpringBootApplication
public class AccessingDataMysqlApplication {
public static void main(String[] args) {
SpringApplication.run(AccessingDataMysqlApplication.class, args);
}
}
MainController.java
package com.example.accessingdatamysql.rest;
import javax.persistence.NoResultException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.example.accessingdatamysql.model.UserDto;
import com.example.accessingdatamysql.service.UserService;
#RestController
#RequestMapping("/demo")
public class MainController {
#Autowired
private UserService userService;
#Transactional
//#RequestMapping(value = "/add/", method = RequestMethod.POST)
#PostMapping(path="/demo/add")
public String addNewUser(#PathVariable("name") String name, #PathVariable("email") String email,
#PathVariable("surname") String surname) {
UserDto n = new UserDto();
n.setName(name);
n.setSurname(surname);
n.setEmail(email);
userService.create(n);
return "User Saved in DB";
}
#SuppressWarnings({ "rawtypes", "unchecked" })
//#RequestMapping(value = "/fetchUser/{name}", method = RequestMethod.GET)
#GetMapping("/demo/first")
public ResponseEntity<UserDto> fetchUser(#PathVariable("name") String name) {
System.out.println(name);
try {
UserDto namefound = userService.findFirstByName(name);
System.out.println("Name found");
ResponseEntity<UserDto> user = new ResponseEntity<UserDto>(namefound, HttpStatus.OK);
return user;
} catch(NoResultException ne) {
System.out.println("User not found");
return new ResponseEntity("User not found with name : " + name, HttpStatus.NOT_FOUND);
}
}
}
UserService.java
package com.example.accessingdatamysql.service;
import org.springframework.stereotype.Service;
import com.example.accessingdatamysql.model.UserDto;
#Service
public interface UserService {
UserDto findFirstByName(String name);
void create(UserDto user);
}
UserServiceImpl.java
package com.example.accessingdatamysql.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import com.example.accessingdatamysql.model.UserDto;
import com.example.accessingdatamysql.model.UserEntity;
import com.example.accessingdatamysql.repo.UserRepository;
import com.example.accessingdatamysql.util.UserMapper;
#Service
public class UserServiceImpl implements UserService {
#Autowired
private UserRepository userRepository;
#Autowired
UserMapper mapper;
#Override
public UserDto findFirstByName(String name) {
UserEntity entity = userRepository.findFirstByName(name);
return mapper.toDtoMapper(entity);
}
#Override
public void create(UserDto user) {
UserEntity entity = mapper.toEntityMapper(user);
userRepository.create(entity);
}
}
UserMapper.java
package com.example.accessingdatamysql.util;
import org.mapstruct.Mapper;
import com.example.accessingdatamysql.model.UserDto;
import com.example.accessingdatamysql.model.UserEntity;
#Mapper(componentModel = "spring")
public interface UserMapper {
public UserEntity toEntityMapper (UserDto user);
public UserDto toDtoMapper (UserEntity userEntity);
}
UserRepository.java
package com.example.accessingdatamysql.repo;
import org.springframework.stereotype.Repository;
import com.example.accessingdatamysql.model.UserEntity;
#Repository
public interface UserRepository {
UserEntity findFirstByName(String name);
void create(UserEntity entity);
}
UserRepositoryImpl.java
package com.example.accessingdatamysql.service;
import javax.persistence.EntityManager;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import org.springframework.stereotype.Component;
import com.example.accessingdatamysql.model.UserEntity;
import com.example.accessingdatamysql.repo.UserRepository;
#Component
public class UserRepositoryImpl implements UserRepository {
private final EntityManager em;
public UserRepositoryImpl(EntityManager entityManager) {
this.em = entityManager;
}
#Override
public UserEntity findFirstByName(String name) {
CriteriaBuilder builder = em.getCriteriaBuilder();
CriteriaQuery<UserEntity> criteria = builder.createQuery(UserEntity.class);
Root<UserEntity> root = criteria.from(UserEntity.class);
criteria.select(root).where(builder.equal(root.get("name"), name));
criteria.orderBy(builder.asc(root.get("timestamp")));
TypedQuery<UserEntity> query = em.createQuery(criteria).setMaxResults(1);
return query.getSingleResult();
}
#Override
// per la creazione//
public void create(UserEntity entity) {
em.persist(entity);
}
}
UserDto.java
package com.example.accessingdatamysql.model;
import java.io.Serializable;
import java.sql.Timestamp;
public class UserDto implements Serializable {
/**
*
*/
private static final long serialVersionUID = -7621330660870602403L;
/**
*
*/
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Timestamp getTimestamp() {
return timestamp;
}
public void setTimestamp(Timestamp timestamp) {
this.timestamp = timestamp;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getSurname() {
return surname;
}
public void setSurname(String surname) {
this.surname = surname;
}
private Timestamp timestamp;
private String email;
private String surname;
}
If you need I can also insert User.java and the pom, but the pom has no problems as the dependencies are all correct.
You have an additional demo in your path descriptions for GET and POST methods, you should remove it:
#GetMapping("/demo/first")
#PostMapping(path = "/demo/first")
It should be :
#GetMapping("/first")
#PostMapping(path = "/first")
This because you have already defined demo in the RequestMapping annotation in the class level.
I have this code of hibernateTemplate to verify the username and password but this code was working fine with MYSQL but failed in Oracle and was showing some problem in DAO class as it created the table but not saving the value.For project it was necessary to use Oracle
package com.infotech.dao.impl;
import java.util.List;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate4.HibernateTemplate;
import org.springframework.stereotype.Repository;
import com.infotech.dao.StudentDAO;
import com.infotech.model.Student;
#Repository("studentDAO")
public class StudentDAOImpl implements StudentDAO {
#Autowired
private HibernateTemplate hibernateTemplate;
public void setHibernateTemplate(HibernateTemplate hibernateTemplate) {
this.hibernateTemplate = hibernateTemplate;
}
public HibernateTemplate getHibernateTemplate() {
return hibernateTemplate;
}
#Override
public boolean saveStudent(Student student) {
int id = (Integer)hibernateTemplate.save(student);
if(id>0)
return true;
return false;
}
#SuppressWarnings("unchecked")
#Override
public Student getStudentDetailsByEmailAndPassword(String email,String password){
DetachedCriteria detachedCriteria = DetachedCriteria.forClass(Student.class);
detachedCriteria.add(Restrictions.eq("email", email));
detachedCriteria.add(Restrictions.eq("password", password));
List<Student> findByCriteria = (List<Student>) hibernateTemplate.findByCriteria(detachedCriteria);
if(findByCriteria !=null && findByCriteria.size()>0)
return findByCriteria.get(0);
else
return null;
}
}
**Now I again changed the DAO class instead of HibernateTemplate I used Session Interface and now value are saving in Database but the Validation of username and password is not taking place some issues in Hibernate Template.Please suggest changes instead of hibernate template what should I use
import java.util.List;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate4.HibernateTemplate;
import org.springframework.stereotype.Repository;
import com.infotech.dao.StudentCredentialDao;
import com.infotech.model.Student;
import com.infotech.model.StudentCredential;
#Repository("StudentCredentialDAO")
public class StudentCredentialDaoImpl implements StudentCredentialDao {
#Autowired
private SessionFactory sessionFactory;
#Autowired
private HibernateTemplate hibernateTemplate;
public SessionFactory getSessionFactory() {
return sessionFactory;
}
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
#Override
public boolean saveStudentCred(StudentCredential stuCred) {
Session session = this.sessionFactory.openSession();
Transaction tx = session.beginTransaction();
session.save(stuCred);
tx.commit();
session.close();
return true;
}
#SuppressWarnings("unchecked")
#Override//This method is creating problem as I need to use something else other than Hibernate Template
public StudentCredential getStudentDetailsByUnameAndPassword(String uname,String password){
DetachedCriteria detachedCriteria = DetachedCriteria.forClass(StudentCredential.class);
detachedCriteria.add(Restrictions.eq("uname", uname));
detachedCriteria.add(Restrictions.eq("password", password));
List<StudentCredential> findByCriteria = (List<StudentCredential>)hibernateTemplate.findByCriteria(detachedCriteria);
if(findByCriteria !=null && Hibernate template .size()>0)
return findByCriteria.get(0);
else
return null;
}
}
#Repository
public class LoginDAOImpl implements LoginDAO {
#Autowired
private SessionFactory sessionFactory;
#Override
public String loginCheck(String customerID, String password) {
Session currentSession = sessionFactory.getCurrentSession();
Query theQuery = currentSession.createQuery("from UserAccount u where u.customerID=:id AND u.password=:pass");
theQuery.setParameter("id", customerID);
theQuery.setParameter("pass", password);
List results = theQuery.list();
if ((results!=null) && (results.size()>0)){
return "success";
}
else {
return "failed";
}
}
You could use in this way
I have abstract user service where I autowired two beans: Repository and AbstractMapper, but when I run test for that class, all faild with NullPointerException. When I run, for example, save test for that service in dubug, it show me that both beans are null. Anybody had this problem? This is my code:
AbstractService
package com.example.shop.service;
import com.example.shop.dto.AbstractMapper;
import com.example.shop.entity.Identifable;
import com.example.shop.repository.IRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.stream.Collectors;
#Service`enter code here`
public abstract class AbstractService<E extends Identifable, D> implements IService<E, D> {
private IRepository<E> repository;
private AbstractMapper<E, D> abstractMapper;
#Autowired
public AbstractService(IRepository<E> repository, AbstractMapper<E, D> abstractMapper) {
this.repository = repository;
this.abstractMapper = abstractMapper;
}
#Override
public D get(Long id) {
E e = repository.get(id);
return abstractMapper.entityToDto(e);
}
#Override
public List<D> getAll() {
List<E> all = repository.getAll();
List<D> allDtos = all.stream()
.map(e -> abstractMapper.entityToDto(e))
.collect(Collectors.toList());
return allDtos;
}
#Override
public E save(D d) {
E e = abstractMapper.dtoToEntity(d);
return repository.save(e);
}
#Override
public E update(D d) {
E e = abstractMapper.dtoToEntity(d);
return repository.update(e);
}
#Override
public E delete(D d) {
E e = abstractMapper.dtoToEntity(d);
return repository.delete(e);
}
#Override
public void deleteAll() {
repository.deleteAll();
}
}
UserServiceImpl
package com.example.shop.service;
import com.example.shop.dto.UserDto;
import com.example.shop.dto.UserMapper;
import com.example.shop.entity.User;
import com.example.shop.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
#Service
public class UserServiceImpl extends AbstractService<User, UserDto> implements UserService {
private UserRepository repository;
private UserMapper userMapper;
#Autowired
public UserServiceImpl(UserRepository repository, UserMapper userMapper) {
super(repository, userMapper);
}
}
Abstract Mapper
package com.example.shop.dto;
import org.springframework.stereotype.Component;
#Component
public interface AbstractMapper<E, D> {
E dtoToEntity(D d);
D entityToDto(E e);
}
User Mapper:
package com.example.shop.dto;
import com.example.shop.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
#Component
public class UserMapper implements AbstractMapper<User, UserDto> {
private AccountMapper accountMapper;
#Autowired
public UserMapper(AccountMapper accountMapper) {
this.accountMapper = accountMapper;
}
#Override
public User dtoToEntity(UserDto dto) {
if (dto == null) {
return null;
}
User user = new User();
user.setId(dto.getId());
user.setEmail(dto.getEmail());
user.setPassword(dto.getPassword());
user.setLogin(dto.getLogin());
user.setAccount(accountMapper.dtoToEntity(dto.getAccountDto()));
return user;
}
#Override
public UserDto entityToDto(User user) {
if (user == null) {
return null;
}
UserDto dto = new UserDto();
dto.setEmail(user.getEmail());
dto.setLogin(user.getLogin());
dto.setPassword(user.getPassword());
dto.setId(user.getId());
dto.setAccountDto(accountMapper.entityToDto(user.getAccount()));
return dto;
}
}
Class with #SpringBootApplication
package com.example.shop;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication
public class ShopApplication implements CommandLineRunner {
public static void main(String[] args) {
SpringApplication.run(ShopApplication.class, args);
}
#Override
public void run(String... args) throws Exception {
System.out.println("Test");
}
}
And my tests for Service:
package com.example.shop.service;
import com.example.shop.dto.UserDto;
import com.example.shop.entity.User;
import com.example.shop.repository.IRepository;
import org.junit.After;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import static org.mockito.Mockito.*;
#RunWith(SpringRunner.class)
#SpringBootTest
public class UserServiceImplTest {
private static final Long VALID_ID = 1L;
#Mock
private IRepository<User> repository;
#InjectMocks
private UserServiceImpl service;
#After
public void tearDown() {
repository.deleteAll();
}
#Test
public void get() {
service.get(VALID_ID);
verify(repository, times(1)).get(anyLong());
}
#Test
public void save() {
UserDto dto = createUser();
service.save(dto);
verify(repository, times(1)).save(any());
}
#Test
public void getAll() {
service.getAll();
verify(repository, times(1)).getAll();
}
#Test
public void update() {
UserDto dto = createUser();
service.update(dto);
verify(repository, times(1)).update(any());
}
#Test
public void delete() {
UserDto dto = createUser();
service.delete(dto);
verify(repository, times(1)).delete(any());
}
#Test
public void deleteAll() {
service.deleteAll();
verify(repository, times(1)).deleteAll();
}
private UserDto createUser() {
return new UserDto();
}
}
There are several problems with this code. First of all you do not need to annotate the abstract classes with service or component. Abstract classes cannot be instantiated, therefore there is no bean.
Second: autowire of classes having generics wont work. As soon as you have several bean, it wont be unique anymore.
Checkout if your classes get instantiated. Maybe you need to add #componentscan.
Your test is located under: com.example.shop.service and therefore it only scans the beans under this package. You should either move your test or add the beans by using the componentscan annotation
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.
I'm working on little Spring MVC CRUD application. Got some strange problems:
configuration class:
package sbk.spring.simplejc.config;
import java.util.Properties;
import javax.annotation.Resource;
import javax.sql.DataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.hibernate4.HibernateTransactionManager;
import org.springframework.orm.hibernate4.LocalSessionFactoryBean;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.JstlView;
import org.springframework.web.servlet.view.UrlBasedViewResolver;
#Configuration //Specifies the class as configuration
#ComponentScan("sbk.spring.simplejc") //Specifies which package to scan
//#Import({DataBaseConfig.class})
#EnableTransactionManagement
#PropertySource("classpath:application.properties")
#EnableWebMvc //Enables to use Spring's annotations in the code
public class WebAppConfig extends WebMvcConfigurerAdapter{
private static final String PROPERTY_NAME_DATABASE_DRIVER = "db.driver";
private static final String PROPERTY_NAME_DATABASE_PASSWORD = "db.password";
private static final String PROPERTY_NAME_DATABASE_URL = "db.url";
private static final String PROPERTY_NAME_DATABASE_USERNAME = "db.username";
private static final String PROPERTY_NAME_HIBERNATE_DIALECT = "hibernate.dialect";
private static final String PROPERTY_NAME_HIBERNATE_SHOW_SQL = "hibernate.show_sql";
private static final String PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN = "entitymanager.packages.to.scan";
#Resource
private Environment env;
#Bean
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(env.getRequiredProperty(PROPERTY_NAME_DATABASE_DRIVER));
dataSource.setUrl(env.getRequiredProperty(PROPERTY_NAME_DATABASE_URL));
dataSource.setUsername(env.getRequiredProperty(PROPERTY_NAME_DATABASE_USERNAME));
dataSource.setPassword(env.getRequiredProperty(PROPERTY_NAME_DATABASE_PASSWORD));
return dataSource;
}
#Bean
public LocalSessionFactoryBean sessionFactory() {
LocalSessionFactoryBean sessionFactoryBean = new LocalSessionFactoryBean();
sessionFactoryBean.setDataSource(dataSource());
sessionFactoryBean.setPackagesToScan(env.getRequiredProperty(PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN));
sessionFactoryBean.setHibernateProperties(hibProperties());
return sessionFactoryBean;
}
private Properties hibProperties() {
Properties properties = new Properties();
properties.put(PROPERTY_NAME_HIBERNATE_DIALECT, env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_DIALECT));
properties.put(PROPERTY_NAME_HIBERNATE_SHOW_SQL, env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_SHOW_SQL));
return properties;
}
#Bean
public HibernateTransactionManager transactionManager() {
HibernateTransactionManager transactionManager = new HibernateTransactionManager();
transactionManager.setSessionFactory(sessionFactory().getObject());
return transactionManager;
}
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
}
#Bean
public UrlBasedViewResolver setupViewResolver() {
UrlBasedViewResolver resolver = new UrlBasedViewResolver();
resolver.setPrefix("/WEB-INF/views/");
resolver.setSuffix(".jsp");
resolver.setViewClass(JstlView.class);
return resolver;
}
}
application.properties:
#DB properties:
db.driver=com.microsoft.sqlserver.jdbc.SQLServerDriver
db.url=jdbc:sqlserver://127.0.0.1:1433;databaseName=Examples
db.username=sa
db.password=
#Hibernate Configuration:
hibernate.dialect=org.hibernate.dialect.SQLServerDialect
hibernate.show_sql=true
entitymanager.packages.to.scan=sbk.spring.simplejc.entity
#Entity class:
package sbk.spring.simplejc.entity;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
#Entity
#Table(name="Team")
public class Team {
#Id
#GeneratedValue
private Integer id;
private String name;
private Integer rating;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getRating() {
return rating;
}
public void setRating(Integer rating) {
this.rating = rating;
}
}
Controller class:
package sbk.spring.simplejc.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import sbk.spring.simplejc.service.ITeamService;
#Controller
public class TeamController {
#Autowired
ITeamService service;
#RequestMapping(value="/")
public ModelAndView goToHelloPage() {
ModelAndView view = new ModelAndView();
view.addObject("teamList", service.listTeams());
return view;
}
}
Error stack trace:
org.hibernate.hql.internal.ast.QuerySyntaxException: Team is not mapped [from Team]
org.hibernate.hql.internal.ast.util.SessionFactoryHelper.requireClassPersister(SessionFactoryHelper.java:180)
org.hibernate.hql.internal.ast.tree.FromElementFactory.addFromElement(FromElementFactory.java:110)
org.hibernate.hql.internal.ast.tree.FromClause.addFromElement(FromClause.java:93)
org.hibernate.hql.internal.ast.HqlSqlWalker.createFromElement(HqlSqlWalker.java:324)
org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.fromElement(HqlSqlBaseWalker.java:3420)
org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.fromElementList(HqlSqlBaseWalker.java:3309)
org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.fromClause(HqlSqlBaseWalker.java:706)
org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.query(HqlSqlBaseWalker.java:562)
org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.selectStatement(HqlSqlBaseWalker.java:299)
org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.statement(HqlSqlBaseWalker.java:247)
org.hibernate.hql.internal.ast.QueryTranslatorImpl.analyze(QueryTranslatorImpl.java:248)
org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:183)
org.hibernate.hql.internal.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:136)
org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:105)
org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:80)
org.hibernate.engine.query.spi.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:168)
org.hibernate.internal.AbstractSessionImpl.getHQLQueryPlan(AbstractSessionImpl.java:221)
org.hibernate.internal.AbstractSessionImpl.createQuery(AbstractSessionImpl.java:199)
org.hibernate.internal.SessionImpl.createQuery(SessionImpl.java:1777)
sbk.spring.simplejc.dao.HibTeamDAO.listTeams(HibTeamDAO.java:23)
sbk.spring.simplejc.service.TeamService.listTeams(TeamService.java:27)
I haven't got a clue about this issue.
Update
DAO class:
package sbk.spring.simplejc.dao;
import java.util.List;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import sbk.spring.simplejc.entity.Team;
#Repository
public class HibTeamDAO implements TeamDAO {
#Autowired
private SessionFactory sessionFactory;
public void addTeam(Team team) {
sessionFactory.getCurrentSession().save(team);
}
public void updateTeam(Team team) {
sessionFactory.getCurrentSession().update(team);
}
#SuppressWarnings("unchecked")
public List<Team> listTeams() {
return sessionFactory.getCurrentSession().createQuery("from Team").list();
}
#SuppressWarnings("unchecked")
public Team getTeamById(Integer teamID) {
Session session = sessionFactory.getCurrentSession();
List<Team> listTeam = session.createQuery("from Team t where t.id = :teamID")
.setParameter("teamID", teamID)
.list();
return listTeam.size() > 0 ? (Team)listTeam.get(0) : null;
}
public void removeTeam(Integer teamID) {
Team team = (Team) sessionFactory.getCurrentSession().load(Team.class, teamID);
if(team != null){
sessionFactory.getCurrentSession().delete(team);
}
}
#Override
public Integer count() {
return (Integer) sessionFactory.getCurrentSession().createQuery("select count(t) from Team t").uniqueResult();
}
}
TeamController class:
package sbk.spring.simplejc.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import sbk.spring.simplejc.service.ITeamService;
#Controller
public class TeamController {
#Autowired
ITeamService service;
#RequestMapping(value="/")
public ModelAndView goToHelloPage() {
ModelAndView view = new ModelAndView();
view.addObject("teamList", service.listTeams());
return view;
}
}
Update
Now I got rid from this problem by changing DAO method from
return sessionFactory.getCurrentSession().createQuery("from Team").list();
to
return sessionFactory.getCurrentSession().createQuery("from sbk.spring.simplejc.entity.Team").list();
But received another issue: every query return null despite of existing rows in Team table.
Update
Finally I noticed warning messages:
Feb 15, 2014 7:01:05 PM org.hibernate.hql.internal.QuerySplitter concreteQueries
WARN: HHH000183: no persistent classes found for query class: from sbk.spring.simplejc.entity.Team
Update
At least I've sorted out this issue by adding next row of code in dataSource bean definition in WebAppConfig:
public LocalSessionFactoryBean sessionFactory() {
LocalSessionFactoryBean sessionFactoryBean = new LocalSessionFactoryBean();
sessionFactoryBean.setDataSource(dataSource());
sessionFactoryBean.setAnnotatedClasses(new Class[]{Team.class});//new row!!!
sessionFactoryBean.setPackagesToScan(env.getRequiredProperty(PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN));
sessionFactoryBean.setHibernateProperties(hibProperties());
return sessionFactoryBean;
}
In my case it was because I didn't have the hibernate packagesToScan property. I see that you have it. May be this comment will be useful for someone who missed it.
"No, in this instance I've got org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected token: * near line 1, column 8 [select * from Team] – Sobik Feb 15 at 10:29"
Instead "Select * from Team" try write "from Team". Because Hibernate works with java entity.