Injected Beans are null in abstract class - java

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

Related

How do I test my CustomUserDetailsService?

I have a CustomerUserDetailsService class, which is part of an implementation of Spring Boot authentication. I have tested my code manually, and it works correctly, allowing me to successfully log in to my app. However, I am unable to work out how to test the CustomerUserDetailsService.
As a unit test, I believe I would need to mock the userRepository member variable, but whatever I try in my test fails, the reason being userRepository is set to null. I've tried adding the #Repository annotation to userRepository but am told that is not allowed because it is an interface. There's also the fact that loadUserByUsername returns an instance of CustomUserDetails, which is just an implementation of an interface, so I have no idea how I'd mock that dependency?
I've also tried doing some kind of integration test but had similar issues, probably due to incorrect annotations on the test itself. In an ideal world, I'd prefer a unit test and would be extremely grateful for any guidance as to how to set it up.
These are the relevant classes...
CustomerUserDetailsService:
package com.phil.urlshortener.security;
import com.phil.urlshortener.model.User;
import com.phil.urlshortener.repositories.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
public class CustomUserDetailsService implements UserDetailsService {
#Autowired private UserRepository userRepository;
#Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userRepository.findByUsername(username);
if (user == null) {
throw new UsernameNotFoundException("User not found");
}
return new CustomUserDetails(user);
}
}
User:
package com.phil.urlshortener.model;
import lombok.Data;
import javax.persistence.*;
#Data
#Entity
public class User {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column(nullable = false, unique = true, length = 50)
private String username;
#Column(nullable = false, length = 64)
private String password;
}
UserRepository:
package com.phil.urlshortener.repositories;
import com.phil.urlshortener.model.User;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.CrudRepository;
public interface UserRepository extends CrudRepository<User, Long> {
#Query("SELECT u FROM User u WHERE u.username = ?1")
User findByUsername(String username);
}
CustomUserDetails:
package com.phil.urlshortener.security;
import com.phil.urlshortener.model.User;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import java.util.Collection;
public class CustomUserDetails implements UserDetails {
private final User user;
public CustomUserDetails(User user) {
this.user = user;
}
#Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return null;
}
#Override
public String getPassword() {
return user.getPassword();
}
#Override
public String getUsername() {
return user.getUsername();
}
#Override
public boolean isAccountNonExpired() {
return true;
}
#Override
public boolean isAccountNonLocked() {
return true;
}
#Override
public boolean isCredentialsNonExpired() {
return true;
}
#Override
public boolean isEnabled() {
return true;
}
}
Maybe you forgot to use mockito annotation #RunWith(MockitoJUnitRunner.class).
Here it's the unit test for CustomUserDetailsService :
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.test.util.ReflectionTestUtils;
import static org.junit.Assert.*;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
#RunWith(MockitoJUnitRunner.class)
public class CustomUserDetailsService {
#Mock
private UserRepository userRepository;
private CustomUserDetailsService customUserDetailsService;
#Before
public void setUp() throws Exception {
customUserDetailsService = new CustomUserDetailsService(userRepository);
}
#Test
public void GIVEN_username_THEN_return_user_details() {
//Arrange
final String username = "existingUserName";
final User user = mock(User.class);
when(userRepository.findByUsername(username)).thenReturn(user);
//Act
final UserDetails userDetails = customUserDetailsService.loadUserByUsername(username);
//Assert
assertNotNull(userDetails);
assertEquals(user, ReflectionTestUtils.getField(userDetails, "user"));
}
}

mock Field Injected dependancies in service layer including dozer mapper

My service layer class is like below.
CategoryServiceImpl.java
#Service
public class CategoryServiceImpl implements CategoryService {
#Autowired
private CategoryRepository categoryRepository;
#Autowired
private DozerBeanMapper dozerBeanMapper;
#Override
public CategoryDto createCategory(CategoryDto categoryDto) {
Category category = categoryRepository.save(dozerBeanMapper.map(categoryDto, Category.class));
return dozerBeanMapper.map(category, CategoryDto.class);
}
#Override
public List<CategoryDto> findAllCategories() {
List<Category> all = categoryRepository.findAll();
return all.stream().map(s -> dozerBeanMapper.map(s, CategoryDto.class)).collect(Collectors.toList());
}
}
MY Test Class is like below.
import com.os.eprocurement.core.dto.CategoryDto;
import com.os.eprocurement.core.model.Category;
import com.os.eprocurement.repository.CategoryRepository;
import com.os.eprocurement.service.impl.CategoryServiceImpl;
import org.dozer.DozerBeanMapper;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.junit.MockitoJUnitRunner;
import java.util.Arrays;
import java.util.List;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.when;
//#SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
#RunWith(MockitoJUnitRunner.class)
public class CategoryServiceTest {
#InjectMocks
private CategoryServiceImpl categoryService;
#Mock
private CategoryRepository categoryRepository;
#Mock
private DozerBeanMapper dozerBeanMapper;
#Before
public void setup() {
MockitoAnnotations.initMocks(this);
}
#Test
public void findAllCategories() {
Category category = new Category();
category.setRootCategoryId("345");
category.setCategoryName("Computers");
category.setCategoryDescription("PC");
category.setBusinessUnitId("123");
CategoryDto categoryDto = new CategoryDto();
categoryDto.setRootCategoryId("345");
categoryDto.setCategoryName("Computers");
categoryDto.setCategoryDescription("PC");
categoryDto.setBusinessUnitId("123");
List<Category> categoryList = Arrays.asList(category);
// List<CategoryDto> categoryDtos = new ArrayList<>();
when(categoryRepository.findAll()).thenReturn(categoryList);
when(dozerBeanMapper.map(categoryDto, CategoryDto.class)).thenReturn(categoryDto);
List<CategoryDto> allCategories = categoryService.findAllCategories();
assertEquals(1, allCategories.size());
}
}
It always emit a nullpointer exception when running above Test. But if I use field injection in service layer as below,
CategoryServiceImpl.java
....
#Autowired
public CategoryServiceImpl(CategoryRepository categoryRepository, DozerBeanMapper dozerBeanMapper) {
this.categoryRepository = categoryRepository;
this.dozerBeanMapper = dozerBeanMapper;
}
....
and modify Test as below,
CategoryServiceTest.java
...
#Before
public void setup() {
MockitoAnnotations.initMocks(this);
categoryService = new CategoryServiceImpl(categoryRepository, dozerBeanMapper);
}
...
Test start running fine. But the issue is, since this is a large project and have already used Field Injection in almost everywhere, It is impossible to change it back to Constructor Injection. Are there any way to avoid this NPE while using Field Injection?
I receive NPE from this line,
CategoryServiceTest.java
...
when(categoryRepository.findAll()).thenReturn(categoryList);
...

how to Mockito unit test with Session Beans

I am learning to write a UnitTest for my JSF project which has ManangedBeans and Session Beans
I have a problem invoking the EJB from Mockito test
package Test;
import ejb.CountrySession;
import java.io.Serializable;
import javax.ejb.EJB;
import javax.inject.Named;
import javax.faces.view.ViewScoped;
#Named(value = "countryMB")
#ViewScoped
public class CountryMB implements Serializable {
#EJB
private CountrySession countSession;
//
private String countryName;
//
private StatusMsg msg;
public CountryMB() {
}
public void setMsg(StatusMsg msg) {
this.msg = msg;
}
public void setCountSession(CountrySession countSession) {
this.countSession = countSession;
}
public String getCountryName() {
return countryName;
}
public void setCountryName(String countryName) {
this.countryName = countryName;
}
public void ajaxAll() {
}
public void saveCountry() {
if (countryName != null && !countryName.trim().isEmpty()) {
boolean chk = countSession.chkCountry(countryName);
if (!chk) {
chk = countSession.addCountry(countryName);
if (chk) {
msg.addInfo("Add Country", "New Country added");
} else {
msg.addError("Add Country", "Unable to add Country");
}
} else {
msg.addWarn("Add Country", "Country already exists");
}
} else {
msg.addWarn("Add Country", "Required parameter not available");
}
}
}
Now in my Test Code i have the following
package Test;
import ejb.CountrySession;
import entities.Country;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.Query;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
public class CountryMBTest {
#Mock
private CountryMB countryMB;
#Mock
private StatusMsg sm;
#Mock
private CountrySession countSession;
#Mock
private EntityManager em;
#Mock
private Query qry;
#Before
public void setup() {
MockitoAnnotations.initMocks(this);
countryMB = new CountryMB();
countryMB.setMsg(sm);
countryMB.setCountSession(countSession);
}
#After
public void after() {
countryMB = null;
}
#Test
public void infoCountrySave() {
countryMB.setCountryName("Test");
countryMB.saveCountry();
verify(sm).addInfo("Add Country", "New Country added");
}
#Test
public void errorCountrySave() {
countryMB.setCountryName("Test");
countryMB.saveCountry();
verify(sm).addError("Add Country", "Unable to add Country");
}
#Test
public void warnCountrySave() {
countryMB.setCountryName("Test");
countryMB.saveCountry();
verify(sm).addWarn("Add Country", "Country already exists");
}
#Test
public void chkCountSave() {
List<Country> countLst = null;
Country dum = mock(Country.class);
EntityManager em = mock(EntityManager.class);
Mockito.when(em.find(Country.class, 111)).thenReturn(dum);
CountrySession cs = Mockito.mock(CountrySession.class);
Mockito.when(cs.chkCountry("Test")).thenCallRealMethod();
Mockito.when(cs.getEm()).thenReturn(em);
String name = "Test";
Assert.assertNull(cs.chkCountry(name));
}
}
My table has only one Record pk=1, Country=Test
The above test code never check the session beans, it just throw
java.lang.NullPointerException
at ejb.CountrySession.chkCountry(CountrySession.java:67)
at Test.CountryMBTest.chkCountSave(CountryMBTest.java:112)
And for infoCountrySave() & warnCountrySave() it just never check the supplied value in the database.
As i have never used any UnitTest earlier so i really don't know if what i am doing is correct, moreover i could not figure out any working code by googling.
It will be of great help if anyone can guide me to some resource available online or even let me know what is that i need to correct to get the above mockito test work with the ejb part.
Change #Mock with #InjectMocks for
private CountryMB countryMB
and when you get java.lang.NullPointerException. Mostly you miss inject some class or some dependency on by called when

How to set the properties of a Spring prototype bean via Java configs?

If I #Autowire the BlahService with SCOPE_PROTOTYPE below, I get the IllegalArgumentException because name is null:
#Component
#Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
class BlahService {
private String name;
#PostConstruct
public void init()
{
If (name == null) {
throw new IllegalArgumentException("");
}
}
private void setName(String name) {
this.name = name;
}
}
class Foo {
#Autowired
private BlahService service;
}
What's the proper way to ensure name gets set in BlahService?
I assume, you have something like
#Bean
public BlahService getBlahService() {
Blahservice bean = new BlahService();
return bean;
}
and you have to modify it to
#Bean
#Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public BlahService getBlahService() {
Blahservice bean = new BlahService();
bean.setName( findProperName() );
retunrn bewn;
}
Full tests is:
Main
package test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Main {
public static void main(String[] args) {
ApplicationContext ac = new AnnotationConfigApplicationContext(Config.class);
BlahService bean1 = ac.getBean(BlahService.class);
System.out.println(bean1.getName());
BlahService bean2 = ac.getBean(BlahService.class);
System.out.println(bean2.getName());
FooService bean3 = ac.getBean(FooService.class);
bean3.print();
}
}
BlahService
package test;
public class BlahService {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
FooService
package test;
import org.springframework.beans.factory.annotation.Autowired;
public class FooService {
#Autowired
BlahService blahService;
public void print() {
System.out.println("FooService#print: " + blahService.getName());
}
}
Config
package test;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;
#Configuration
public class Config {
static int counter = 0;
#Bean
#Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public BlahService getBlahService() {
BlahService bean = new BlahService();
bean.setName("name" + counter++);
return bean;
}
#Bean
public FooService getFooService () {
return new FooService();
}
}
executing Main#main prints:
name1
name2
FooService#print: name0
edit (extended)
JUnit
package test;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(classes=Config.class)
public class MyTest {
#Autowired
BlahService blahService;
#Autowired
FooService fooService;
#Test
public void test() {
System.out.println(blahService.getName());
fooService.print();
}
}
prints:
name1
FooService#print: name0

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