Why declare always Interfaces for DAO - spring

Why we have always to declare first a interface to implement our DAO classes like this
Interface :
public interface IRegion<T extends Serializable> {
List<T> findAll();
}
DAO Class :
#Transactional
#Repository
public class RegionDAO implements IRegion < Region > {
#Autowired
private SessionFactory sessionFactory;
#Override
public List<Region> findAll() {
return sessionFactory.getCurrentSession().createQuery("from Region").list();
}
}
Controller :
#Controller
public class welcome {
#Autowired
private IRegion<Region> regionI;
....
}
But it works also when I keep just my DAO class and I remove the interface
#Repository
#Transactional
public class RegionDAO {
#Autowired
private SessionFactory sessionFactory;
public List<Region> findAll() {
return sessionFactory.getCurrentSession().createQuery("from Region").list();
}
}
Controller:
#Controller
public class welcome {
#Autowired
private RegionDAO regionDAO;
....
}
So why we have to add interfaces ?

Related

Object not initialized with autowire

I use spring boot 3
I created a object manually, FormGenerator, because everytime I use is in my advance search, some field need to be reset.
So I think the scope prototype is ok for that
#Repository
public class SchoolRepositoryCustomImpl extends SimpleJpaRepository<School, Long> implements SchoolRepositoryCustom {
#Override
public List<School> advanceSearch(SchoolSearch search) {
FormGenerator qg = new FormGenerator();
}
...
}
#Scope("prototype")
public class FormGenerator {
private int fieldCounter=0;
#Autowired
private EntityManager entityManager;
...
}
When I run application, entityManager is null?
It is null because you created the object manually by calling the constructor. You need to obtain it from the ApplicationContext. Something like this:
#Repository
public class SchoolRepositoryCustomImpl extends SimpleJpaRepository<School, Long> implements SchoolRepositoryCustom {
#Autowired
private ApplicationContext applicationContext;
#Override
public List<School> advanceSearch(SchoolSearch search) {
FormGenerator qg = applicationContext.getBean(FormGenerator.class);
}
...
}

Why can't #Autowired a JPA repository - Spring boot + JPA

I'm giving this error:
Parameter 0 of constructor in x.microservice.module.business.application.BusinessCreator required a bean of type 'x.microservice.module.business.infrastructure.HibernateJpaRepository' that could not be found.
The injection point has the following annotations:
- #org.springframework.beans.factory.annotation.Autowired(required=false)
Action:
Consider defining a bean of type 'x.microservice.module.business.infrastructure.HibernateJpaRepository' in your configuration.
The controller:
#Slf4j
#RestController
public final class BusinessPostController {
#Autowired
private BusinessCreator creator;
#PostMapping(value = "/business")
public ResponseEntity create(#RequestBody Request request){
BusinessCreatorDto businessCreatorDto = new BusinessCreatorDto(IdentifierEpoch.generate(),request.getName());
return ResponseEntity.ok(
creator.create(businessCreatorDto)
);
}
}
The Application Layer:
#AllArgsConstructor
#Service
public class BusinessCreator {
#Autowired
private HibernateJpaRepository repository;
public BusinessResponse create(BusinessCreatorDto dto){
Business business = new Business(dto.getId(), dto.getName());
repository.save(business);
return BusinessResponse.fromAggregate(business);
}
}
In the Infrastructure layer
#Repository
public abstract class HibernateJpaRepository implements JpaRepository<Business, Long> {
}
The boot Application:
#EnableJpaRepositories
#SpringBootApplication
public class MicroserviceApplication {
public static void main(String[] args) {
SpringApplication.run(MicroserviceApplication.class, args);
}
}
All dependencies are resolved and the others classes I believe that are irrellevant.
Any suggestions? Thank you very much
Probably, the error cause is HibernateJpaRepository - it has to be an interface that extends JpaRepository.
You could write your own Repository in a interface:
#Repository
public interface HibernateJpaRepository extends JpaRepository < Business, Long > {
}
Then your Class:
#AllArgsConstructor
#Service
public class BusinessCreator {
#Autowired
private HibernateJpaRepository repository;
public BusinessResponse create(BusinessCreatorDto dto){
Business business = new Business(dto.getId(), dto.getName());
repository.save(business);
return BusinessResponse.fromAggregate(business);
}
}

Spring #Transactional method call by the method of another class?

I just wanted to know what is the difference between if transactional method of class to transactional/non transactional method of another class.
Option A:
#Service
class EmployeeService {
#Autowired
Addressdao addressDao;
#Transactional
void insert(Address address) {
addressDao.insert(address);
}
}
#Service
class AddressDao {
#Autowired
JdbcTemplate jdbcTemplate;
#Transactional
void insert(Address address) {
jdbcTemplate.insert(address);
}
}
Option B:
#Service
class EmployeeService {
#Autowired
Addressdao addressDao;
#Transactional
void insert(Address address) {
addressDao.insert(address);
}
}
#Service
class AddressDao {
#Autowired
JdbcTemplate jdbcTemplate;
void insert(Address address) {
jdbcTemplate.insert(address);
}
}

How to use annotation and avoid xml configuration in spring framework

I have designed a packing structure.
Controller
Delegates (which is helper class) - this class do all the business and return the value to Controllers.
Service
Service Implementation
DAO
DAO Implementation.
I want to implement autowired (Annotation) concept and would like to avoid xml configuration such as service and DAO configuration on spring-bean.xml.
This code is not working if I want to avoid xml configuration.
I have done those changes
bean id :loginDelegate, userService, userDao
added the #Service & #Repository annotation to the corresponding service & DAO implementation.
#Controller("loginController")
public class LoginController {
#Autowired
private LoginDelegate loginDelegate;
public LoginDelegate getLoginDelegate() {
return this.loginDelegate;
}
public void setLoginDelegate(LoginDelegate tLoginDelegate) {
this.loginDelegate = tLoginDelegate;
}
#RequestMapping(value="/login.do",method=RequestMethod.GET)
public ModelAndView displayLogin(HttpServletRequest request, HttpServletResponse response) {
log.info("<---displayLogin()--->");
ModelAndView model = new ModelAndView("login");
LoginBean loginBean = new LoginBean();
model.addObject("loginBean", loginBean);
return model;
}
}
public class LoginDelegate {
#Autowired
private IUserService userService;
public IUserService getUserService() {
return this.userService;
}
public void setUserService(IUserService userService) {
this.userService = userService;
}
public boolean isValidUser(String username, String password) throws Exception {
return userService.isValidUser(username, password);
}
}
public interface IUserService {
public boolean isValidUser(UserBean userObj);
public int addUsers(UserBean userObj);
}
public class UserServiceImpl implements IUserService {
#Autowired
private IUserDao userDao;
public IUserDao getUserDao() {
return this.userDao;
}
public void setUserDao(IUserDao userDao) {
this.userDao = userDao;
}
public boolean isValidUser(UserBean userObj) {
return userDao.isExistUser(userObj);
}
#Override
public int addUser(final UserBean userObj) {
return userDao.saveUserDetails(userObj);
}
}
public interface IUserDao {
public boolean isExistUser(UserBean userObj);
public int saveUserDetails(UserBean userObj);
}
public class UserDaoImpl implements IUserDao {
#Autowired
UserBean userObj;
#Autowired
DataSource dataSource ;
public DataSource getDataSource(){
return this.dataSource;
}
public void setDataSource(DataSource dataSource){
this.dataSource = dataSource;
}
Use Java-based configuration if you want to completely get rid of XML-based configuration
#Configuration
#ComponentScan(basePackages = "com.acme")
public class AppConfig {
...
}
The above normal Java class when annotated with #Configuration, makes it a 'Spring Configuration class' (analogous to XML-based configuration).
#ComponentScan annotation scans for classes annotated with #Component, #Controller, #Service, #Repository classes from the package defined during start-up time to get them registered as Spring beans. This can be done in XML also with <context:component-scan base-package="com.acme" />
Refer:http://docs.spring.io/spring-framework/docs/current/spring-framework-reference/html/beans.html#beans-java-instantiating-container-scan

How to test service class with #Autowired

I have a service class MyService which is defined and being used in controller like so:
public interface MyService {
public String someMethod()
}
#Service("myService")
public class MyServiceImpl implements MyService {
public String someMethod() {
return "something";
}
}
#Controller
public class MyController {
#Autowired
public MyService myService;
#RequestMapping(value="/someurl", method=RequestMethod.GET)
public String blah () {
return myService.getsomeMethod();
}
}
I'd like to write a test case for the someMethod method, however, the following doesn't work. How can I wire in the implementation class?
public class MyServiceImplTest {
#Autowired
private MyService myService;
#Test
public void testSomeMethod() {
assertEquals("something", myService.someMethod());
}
}
public class MyServiceImplTest {
private MyService myService = new MyServiceImpl();
#Test
public void testSomeMethod() {
assertEquals("something", myService.someMethod());
}
}
Why inject the bean in your test rather than creating an instance by yourself?
Try this:
#RunWith(SpringJUnit4ClassRunner.class)
// specifies the Spring configuration to load for this test fixture
#ContextConfiguration("yourapplication-config.xml")
Also see the Spring.IO docs for more detail.

Resources