This examples shows how to apply DAO pattern in JPA based Spring application. We are going to use Hibernate as a JPA provider. We are also going to use LocalEntityManagerFactoryBean to load EntityManagerFactory (see last example).
Example
A Generic Dao Interface
public interface Dao<T> {
void save(T t);
T load(long id);
void delete(long id);
void update(T t);
List<T> loadAll();
}
A JPA Entity
@Entity
public class Person {
@Id
@GeneratedValue
private long id;
private String firstName;
private String lastName;
private String address;
.............
}
The DAO implementation
package com.logicbig.example;
import org.springframework.stereotype.Repository;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.PersistenceUnit;
import java.util.List;
@Repository
public class PersonDaoJpaImpl implements Dao<Person> {
@PersistenceUnit
private EntityManagerFactory emf;
@Override
public void save(Person person) {
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
em.persist(person);
em.getTransaction().commit();
em.close();
}
@Override
public Person load(long id) {
EntityManager em = emf.createEntityManager();
Person person = em.find(Person.class, id);
em.close();
return person;
}
@Override
public void delete(long id) {
EntityManager em = emf.createEntityManager();
Person employee = em.find(Person.class, id);
em.getTransaction().begin();
em.remove(employee);
em.getTransaction().commit();
em.close();
}
@Override
public void update(Person person) {
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
em.merge(person);
em.getTransaction().commit();
em.close();
}
@Override
public List<Person> loadAll() {
EntityManager em = emf.createEntityManager();
List<Person> persons = em.createQuery("Select t from Person t")
.getResultList();
em.close();
return persons;
}
}
Note that, we used JPA's @PersistenceUnit annotation on EntityManagerFactory . In Spring application PersistenceAnnotationBeanPostProcessor (implicitly activated with Spring's Java Config) is responsible to process @PersistenceContext and @PersistenceUnit annotations.
The Service Layer
@Service
public class PersonService {
@Autowired
private Dao<Person> dao;
public void savePerson(Person person) {
try {
dao.save(person);
} catch (DataAccessException e) {
e.printStackTrace();
}
}
public List<Person> getAllPersons() {
try {
return dao.loadAll();
} catch (DataAccessException e) {
e.printStackTrace();
}
return null;
}
public Person getPersonById(long id) {
try {
return dao.load(id);
} catch (DataAccessException e) {
e.printStackTrace();
}
return null;
}
public void deletePerson(long id) {
try {
dao.delete(id);
} catch (DataAccessException e) {
e.printStackTrace();
}
}
public void updatePerson(Person person) {
try {
dao.update(person);
} catch (DataAccessException e) {
e.printStackTrace();
}
}
}
The Example Client
@Component
public class ExampleClientBean {
@Autowired
PersonService personService;
public void run() {
System.out.println("'Persisting persons'");
Person person = Person.create("Dana", "Whitley", "464 Gorsuch Drive");
personService.savePerson(person);
person = Person.create("Robin", "Cash", "64 Zella Park");
personService.savePerson(person);
List<Person> allPersons = personService.getAllPersons();
System.out.println("Persons loaded: " + allPersons);
person = personService.getPersonById(2);
System.out.println("Person loaded by id : " + person);
System.out.println("'updating person address with id 2'");
person.setAddress("111 Yellow Hill");
personService.updatePerson(person);
System.out.println("'Deleting person by id 1'");
personService.deletePerson(1);
allPersons = personService.getAllPersons();
System.out.println("Persons loaded: " + allPersons);
}
}
Java Config and main class
package com.logicbig.example;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.orm.jpa.LocalEntityManagerFactoryBean;
@Configuration
@ComponentScan
public class AppConfig {
@Bean
public LocalEntityManagerFactoryBean entityManagerFactoryBean() {
LocalEntityManagerFactoryBean factory = new LocalEntityManagerFactoryBean();
factory.setPersistenceUnitName("example-unit");
return factory;
}
public static void main(String[] args) {
AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext(AppConfig.class);
context.getBean(ExampleClientBean.class).run();
context.getBean(LocalEntityManagerFactoryBean.class).destroy();
}
}
Output
'Persisting persons'
Persons loaded: [Person{id=1, firstName='Dana', lastName='Whitley', address='464 Gorsuch Drive'}, Person{id=2, firstName='Robin', lastName='Cash', address='64 Zella Park'}]
Person loaded by id : Person{id=2, firstName='Robin', lastName='Cash', address='64 Zella Park'}
'updating person address with id 2'
'Deleting person by id 1'
Persons loaded: [Person{id=2, firstName='Robin', lastName='Cash', address='111 Yellow Hill'}]
Example ProjectDependencies and Technologies Used: - spring-context 5.0.1.RELEASE: Spring Context.
- spring-orm 5.0.1.RELEASE: Spring Object/Relational Mapping.
- hibernate-core 5.2.12.Final: The core O/RM functionality as provided by Hibernate.
Implements javax.persistence:javax.persistence-api version 2.1 - h2 1.4.196: H2 Database Engine.
- JDK 1.8
- Maven 3.3.9
|