Enterprise Java

JBoss 4.2.x Spring 3 JPA Hibernate Tutorial Part #2

We continue our tutorial about Spring 3, Hibernate, JPA and JBoss 4.2.x – 4.3 integration.

The last step is to create a Spring service to expose functionality to the end user. We have to create an interface class and the relevant implementation class. First the interface class :
 
 
 
 
 

package com.mycomp.myproject.services;

import com.mycomp.myproject.dto.EmployeeDTO;

public interface ExampleService {
    
    public EmployeeDTO findEmployee(long employeeId);
    public void saveEmployee(long employeeId, String name, String surname, String jobDescription) throws Exception;
    public void updateEmployee(long employeeId, String name, String surname, String jobDescription) throws Exception;
    public void saveOrUpdateEmployee(long employeeId, String name, String surname, String jobDescription) throws Exception;
    public void deleteEmployee(long employeeId) throws Exception;
    
}

As you can see this is a classic Java interface class. We are going to implement Create, Retrieve, Update, Delete (CRUD) functions over out EmployeeDTO object.

Following is the implementation class of the specified interface.

package com.mycomp.myproject.services.impl;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.mycomp.myproject.dao.EmployeeDAO;
import com.mycomp.myproject.dto.EmployeeDTO;
import com.mycomp.myproject.services.ExampleService;

@Service("exampleService")
public class ExampleServiceImpl implements ExampleService {
    
    @Autowired
    private EmployeeDAO employeeDAO;

    @PostConstruct
    public void init() throws Exception {
    }
    
    @PreDestroy
    public void destroy() {
    }

    public EmployeeDTO findEmployee(long employeeId) {
        
        return employeeDAO.findById(employeeId);
        
    }
    
    @Transactional(propagation=Propagation.REQUIRED, rollbackFor=Exception.class)
    public void saveEmployee(long employeeId, String name, String surname, String jobDescription) throws Exception {
            
        EmployeeDTO employeeDTO = employeeDAO.findById(employeeId);
        
        if(employeeDTO == null) {
            employeeDTO = new EmployeeDTO(employeeId, name,surname, jobDescription);
            employeeDAO.persist(employeeDTO);
        }
        
    }
    
    @Transactional(propagation=Propagation.REQUIRED, rollbackFor=Exception.class)
    public void updateEmployee(long employeeId, String name, String surname, String jobDescription) throws Exception {
        
        EmployeeDTO employeeDTO = employeeDAO.findById(employeeId);
        
        if(employeeDTO != null) {
            employeeDTO.setEmployeeName(name);
            employeeDTO.setEmployeeSurname(surname);
            employeeDTO.setJob(jobDescription);
        }

    }
    
    @Transactional(propagation=Propagation.REQUIRED, rollbackFor=Exception.class)
    public void deleteEmployee(long employeeId) throws Exception {
        
        EmployeeDTO employeeDTO = employeeDAO.findById(employeeId);
        
        if(employeeDTO != null)
            employeeDAO.remove(employeeDTO);

    }
    
    @Transactional(propagation=Propagation.REQUIRED, rollbackFor=Exception.class)
    public void saveOrUpdateEmployee(long employeeId, String name, String surname, String jobDescription) throws Exception {
        
        EmployeeDTO employeeDTO = new EmployeeDTO(employeeId, name,surname, jobDescription);
        
        employeeDAO.merge(employeeDTO);
        
    }

}

Things to notice here :

  • We use the @Service(“exampleService”) stereotype annotation so as to declare that this class represents a Spring service by the name “exampleService”. The Spring container will instantiate all services at start up.
  • We use the @Autowire annotation to inject the instance of the DAO class to the “exampleService”. For proper instantiation of the service Spring container has to resolve first all potential references among services, so it instantiates the DAO class and injects the instance to the appropriate field of “exampleService” – the “employeeDAO” field. In case you wonder, the dependency injection is done according to type (Class) and if not satisfied according to name, meaning that if we have defined multiple services of the same type (Class) the one injected would be the one with the same name as the designated field.
  • We use the Java annotations @PostConstruct and @PreDestroy to declare the methods that will be invoked by Spring container after initialization (all dependency injection is done) and prior destruction of the service.
  • We use the @Transactional annotation for all methods that need to perform update operation on the database (INSERT, UPDATE, DELETE)
  • We DO NOT use the @Transactional annotation on methods that perform retrieve (FIND) operations on the database (except for objects that contain lazily initialized references – see below), and/or perform no database operations. That is because every time you invoke a method annotated as transactional, Spring container involves in the invocation JPA‘s entity manager and as a consequence platform’s transaction manager, so as to define the transactional behavior that will be applied, introducing a noticeable performance penalty especially for low latency / high throughput applications.
  • For methods that perform retrieve (FIND) operations for objects that contain lazily initialized references you should use the @Transactional annotation, designating “NESTED” propagation type in order for Spring to maintain Hibernate session open for the entire method call
  • Transactional behavior is applied only on client calls to the service. Transactional behavior is not applied to intra operation calls. For example if a client invokes an operation that is not annotated as transactional and the implementation of the latter introduces a call to another operation of the same service that is annotated transactional then for the combined operations no transactional behavior will be applied.
  • End user should always access the service through the defined interface

That was a big tutorial indeed!

Hope you liked it.

Justin

Byron Kiourtzoglou

Byron is a master software engineer working in the IT and Telecom domains. He is an applications developer in a wide variety of applications/services. He is currently acting as the team leader and technical architect for a proprietary service creation and integration platform for both the IT and Telecom industries in addition to a in-house big data real-time analytics solution. He is always fascinated by SOA, middleware services and mobile development. Byron is co-founder and Executive Editor at Java Code Geeks.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments
Back to top button