How to implement generic service-layer class in Spring Framework? - java

I try to implement generic service-layer class for basic CRUD operations.
public abstract class AbstractService<T, R extends JpaRepository> {
protected R repository;
public AbstractService(R repository) {
this.repository = repository;
}
public T getOne(final Long id){
return repository.findById(id); // error Required: T, Found: Optional<>
}
}
Why couldnt I use type T without wrapping it to Optional?

You should always follow the good practices that are recommended for JPA and hibernate, so you must create a respository per entity, as this will allow you to develop more scalable applications, however if you want not to have to do this and want an abstract class that allows you To do this, I recommend doing an abstract Dao class that allows you to perform CRUD operations as follows:
import java.io.Serializable;
import java.util.List;
/**
* #author Edy Huiza
* #version 1.0
* Created on 23/11/2018
*/
public interface Dao<T> {
void persist(Object entity);
void persist(Object[] entities);
void update(Object entity);
void delete(Object entity);
void delete(Class entityClass, Serializable id);
List findAll(Class entityClass);
Object get(Class entityClass, Serializable id);
}
And their respective implementation
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import javax.persistence.EntityManager;
import javax.persistence.EntityTransaction;
import javax.persistence.PersistenceContext;
import java.io.Serializable;
import java.util.List;
import java.util.Optional;
import java.util.function.Consumer;
/**
* #author Edy Huiza
* #version 1.0
* Created on 23/11/2018
*/
#Repository
public class SpringHibernateDao implements Dao {
#PersistenceContext
private EntityManager entityManager;
#Override
#Transactional
public void persist(Object entity) {
entityManager.persist(entity);
entityManager.flush();
entityManager.clear();
}
#Override
#Transactional
public void update(Object entity) {entityManager.merge(entity);
}
#Override
#Transactional
public void persist(Object[] entities) {
for (Object entity : entities) {
persist(entity);
}
}
#Override
#Transactional
public void delete(Object entity) {
entityManager.remove(entity);
}
#Override
#Transactional
public void delete(Class entityClass, Serializable id) {
Object entity = get(entityClass, id);
entityManager.remove(entity);
}
#SuppressWarnings("unchecked")
#Override
#Transactional(readOnly = true)
public List findAll(Class entityClass) {
return entityManager.createQuery("from " + entityClass.getName()).getResultList();
}
#Override
#Transactional(readOnly = true)
public Object get(Class entityClass, Serializable id) {
return entityManager.find(entityClass, id);
}
}
And their respective use
#Autowired
Dao dao;
#Override
#Transactional(readOnly = true)
public Dispositivo get(long id) {
return (Dispositivo) dao.get(Dispositivo.class, id);
}

You can try something like this:
public abstract class AbstractService<T, ID, R extends JpaRepository<T, ID>> {
protected R repository;
public AbstractService(R repository) {
this.repository = repository;
}
public Optional<T> getOne(ID id){
return repository.findById(id);
}
}

Related

interface (mock) repository pattern java spring

I am a beginner in Java and in the Spring environment. At the moment I have to implement a CustomerRepository. The CustomerRepository implements a CrudRepository interface. The purpose is that in the repository, customer objects should be stored and retrieved.
I have to use a Mock implementation of the Spring class CrudRepository.
The classdiagram looks like this:
classdiagram
CrudRepository interface:
public interface CrudRepository<Customer, String> {
<S extends Customer> S save( S entity );
...
}
The complete CustomerRepository class:
public class CustomerRepository implements CrudRepository<Customer, String> {
private CrudRepository crudrepository;
/*long count();*/
#Override
public long count() {
long count = crudrepository.count();
return count;
}
/*<S extends Customer> S save( S entity );*/
#Override
public <S extends Customer> S save(S entity) {
crudrepository.save(entity);
return entity;
}
/*<S extends Customer> Iterable<S> saveAll( Iterable<S> entities );*/
#Override
public <S extends Customer> Iterable<S> saveAll(Iterable<S> entities) {
Iterable<S> response = crudrepository.saveAll(entities);
return (Iterable<S>) response;
}
/*Optional<Customer> findById(String id );*/
#Override
public Optional<Customer> findById(String id) {
Optional<Customer> customerResponse = crudrepository.findById(id);
return customerResponse;
}
/*Iterable<Customer> findAllById(Iterable<String> ids );*/
#Override
public Iterable<Customer> findAllById(Iterable<String> ids) {
Iterable<Customer> customerResponse = crudrepository.findAllById(ids);
return customerResponse;
}
/*Iterable<Customer> findAll();*/
#Override
public Iterable<Customer> findAll() {
Iterable<Customer> customerResponse = (Iterable<Customer>) crudrepository
.findAll();
return customerResponse;
}
/*boolean existsById(String id );*/
#Override
public boolean existsById(String id) {
return crudrepository.existsById(id);
}
/*void deleteById(String id );*/
#Override
public void deleteById(String id) {
crudrepository.deleteById(id);
}
/*void delete(Customer entity );*/
#Override
public void delete(Customer entity) {
crudrepository.delete(entity);
}
/*void deleteAllById(Iterable<? extends String> ids );*/
#Override
public void deleteAllById(Iterable<? extends String> entities) {
crudrepository.deleteAll(entities);
}
/*void deleteAll();*/
#Override
public void deleteAll() {
crudrepository.deleteAll();
}
/*void deleteAll(Iterable<? extends Customer> entities );*/
#Override
public void deleteAll(Iterable<? extends Customer> entities) {
crudrepository.deleteAll(entities);
} }
How does that look for you ? Any suggestions ?
I think you are misunderstanding some concepts.
CrudRepository is a Spring object and it's an interface you don't need to implement. You have to extend it and Spring provides you all the magic.
You can achieve your goal simply in the following way:
Repository
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
#Repository
public interface CustomerRepository extends CrudRepository<Customer, String> {
}
Service
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
#Service
public class CustomerService {
#Autowired
private CustomerRepository customerRepository;
public Customer save(Customer customer) {
Customer response = customerRepository.save(customer);
return response;
}
}

How can I implement the Repository pattern using Generic Types with Java Spring

I am trying to find a way I can implement the repository pattern using spring boot with Generic types. So far I looked into this article:
https://thoughts-on-java.org/implementing-the-repository-pattern-with-jpa-and-hibernate/
and tried implementing this solution using generic types based on the solution to this question:
Using generics and jpa EntityManager methods
I attempted to do so using JPA and Hibernate but for me, an error appears when I try returning the class of the entity on the specified type parameter.
the following is my User model using JPA and Hibernate:
package models;
import javax.persistence.*;
#Entity
public class User extends Model {
#Id
#Column(name = "id", updatable = false, nullable = false)
private String id;
public String username;
private String password;
public User(String username, String password) {
super();
this.username = username;
this.password = password;
}
public String getPassword() {
return password;
}
}
The following is my interface for basic CRUD operations:
package repositories;
import models.Model;
import java.util.UUID;
public interface IRepository<T> {
void add(T entity);
void delete(String id);
void update(T entity);
T get(String id);
boolean exists(String id);
}
I then created an abstract class for all repositories to avoid repeating myself for all Models.
package repositories;
import models.Model;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
public abstract class Repository<T> implements IRepository<T>{
private EntityManager em;
public Repository(EntityManager em){
this.em = em;
}
#Override
public void add(T entity) {
em.persist(entity);
}
#Override
public void delete(String id) {
T entity = get(id);
em.remove(entity);
}
#Override
public void update(T entity) {
em.merge(entity);
}
#Override
public T get(String id) {
return em.find(getEntityClass(), id);
}
public boolean exists(String id) {
return em.contains(get(id));
}
// link to an explanation can be found at:https://stackoverflow.com/questions/40635734/using-generics-and-jpa-entitymanager-methods
// when a class extends this class, all is needed is to fill out the method body of to return the class.
public abstract Class<T> getEntityClass();
}
the abstract class is there for me to return the class that belongs to T
and this is the specific repository for Users:
package repositories;
import models.Model;
import models.User;
import javax.persistence.EntityManager;
public class UserRepository<User> extends Repository<User> {
public UserRepository(EntityManager em) {
super(em);
}
#Override
public Class<User> getEntityClass() {
return null;
}
}
Ideally, for the getEntityClass method, I would like to return User.class, but I get an error on the IDE saying "Cannot select from type variable". I have looked at a few more questions online and another thing people tried was either put a parameter of type Class or have a member of type Class within the User repository. I tried both methods and it didn't work, any ideas?
class UserRepository<User> should just be class UserRepository. Otherwise, User is just like T, a generic type. Not the class User.
But you're reinventing the wheel. Learn and use Spring Data JPA, which brings generic repositories, and more.

How to implement a method in a DAO?

I'm using a DAO pattern and Hibernate for my simple JavaFX project for performing CRUD operations. Since I'm new to Hibernate I want to ask you how to implement a particular method.
Firstly I have a solid DAO interface:
import java.util.List;
import org.hibernate.Session;
import java.util.List;
import org.hibernate.Session;
public interface Dao<T, ID> {
public T findById(ID id);
public List<T> findAll();
public T save(T entity);
public void delete(T entity);
public void flush();
public void clear();
public void setSession(Session session);
}
Then I have another interface (more specific):
public interface FotoDao extends Dao<Foto, Integer> {
public List<Foto> findByCarId(Integer id);
}
Followed by another class:
import dao.interfaces.Dao;
import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.util.List;
import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.criterion.Criterion;
import utils.HibernateUtil;
public class AbstractDao<T, ID extends Serializable> implements Dao<T, ID> {
private Class<T> persistentClass;
private Session session;
#SuppressWarnings("unchecked")
public AbstractDao() {
this.persistentClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
}
public void setSession(Session session) {
this.session = session;
}
protected Session getSession() {
if (this.session == null) {
this.session = HibernateUtil.getSessionFactory().getCurrentSession();
}
return this.session;
}
public Class<T> getPersistentClass() {
return persistentClass;
}
#SuppressWarnings("unchecked")
#Override
public T findById(ID id) {
return (T) getSession().load(this.getPersistentClass(), id);
}
#Override
public List<T> findAll() {
return this.findByCriteria();
}
protected List<T> findByCriteria(Criterion... criterion) {
Criteria crit = this.getSession().createCriteria(this.getPersistentClass());
for (Criterion c : criterion) {
crit.add(c);
}
return (List<T>) crit.list();
}
#Override
public T save(T entity) {
this.getSession().saveOrUpdate(entity);
return entity;
}
#Override
public void delete(T entity) {
this.getSession().delete(entity);
}
#Override
public void flush() {
this.getSession().flush();
}
#Override
public void clear() {
this.getSession().clear();
}
}
Then finally I have a concrete class:
public class FotoHibernateDao extends AbstractDao<Foto, Integer> implements FotoDao {
#Override
public List<Foto> findByCarId(Integer id) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
}
How do I implement the findByCarId(Integer id) method?
In my data model I have a table which stores foto urls of cars. And I want this
method to return only images associated with a carId (which is a foreign key).

Generic DAO, Spring, Hibernate

I want to understand how can i implement the generic methods like add, edit, delete and search on my database, i have already made the connection (hibernate) and works fine
I do have this method, that works
Class: GenericDAO
public <T> T save(final T o){
Session session=HibernateUtil.getSessionFactory().openSession();
Transaction trans=session.beginTransaction();
Object object = (T) session.save(o);
trans.commit();
return (T) object;
}
and in Main
GenericDAO gen = new GenericDAO();
gen.save(object);
also i have others methods that i dont know how to use them
Class: GenericDAO
public void delete(final Object object){
Session session=HibernateUtil.getSessionFactory().openSession();
Transaction trans=session.beginTransaction();
session.delete(object);
trans.commit();
}
/***/
public <T> T get(final Class<T> type, final int id){
Session session=HibernateUtil.getSessionFactory().openSession();
Transaction trans=session.beginTransaction();
Object object = (T) session.get(type, id);
trans.commit();
return (T) object;
}
public <T> List<T> getAll(final Class<T> type) {
Session session=HibernateUtil.getSessionFactory().openSession();
Transaction trans=session.beginTransaction();
final Criteria crit = session.createCriteria(type);
List<T> list = crit.list();
trans.commit();
return list;
}
Thank you
I think GenericDAO class is base class. It's not for using directly. Did you check this article ? I checked this article and created a sample project.
Don't repeat the DAO!
Example
GitHub - generic-dao-hibernate sample
For example, you might want to create an API to retrieve all employees list according to MySQL first step example.
Employees table schema is like following:
Base SQL
CREATE TABLE employees (
emp_no INT NOT NULL, -- UNSIGNED AUTO_INCREMENT??
birth_date DATE NOT NULL,
first_name VARCHAR(14) NOT NULL,
last_name VARCHAR(16) NOT NULL,
gender ENUM ('M','F') NOT NULL, -- Enumeration of either 'M' or 'F'
hire_date DATE NOT NULL,
PRIMARY KEY (emp_no) -- Index built automatically on primary-key column
-- INDEX (first_name)
-- INDEX (last_name)
);
O/R Mapping
Hibernate require you to configure mapping object-relation settings. After that, you will enjoy converting object-to-sql and sql-to-object.
Entity class based on SQL
#Entity, #Table, #Id, #Column, #GeneratedValue are from Hibernate
#Data, #NoArgsConstructor are from lombok, it reduces getter/setter code
#XmlRootElement, #XmlAccessorType are from jaxb, you might don't need to use it
#Entity
#Data
#NoArgsConstructor
#Table(name = "employees")
#XmlAccessorType(XmlAccessType.FIELD)
#XmlRootElement
public class Employees implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#Column(name = "emp_no", unique = true)
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer empNo;
#Column(name = "birth_date")
private Date birthDate;
#Column(name = "first_name")
private String firstName;
#Column(name = "last_name")
private String lastName;
#Column(name = "gender")
#Enumerated(EnumType.STRING)
private Gender gender;
#Column(name = "hire_date")
private Date hireDate;
}
Resource Class for Frontend
You always need to write DAO(Data Access Object) for accessing the database. GenericDAO is a method to reduce boilerplate sources codes.
EmployeesResource class
CRUD operations on WEB API
#create, #read, #update or #delete
should be equivalent with
SQL
INSERT, SELECT, UPDATE and DELETE
You need to identify a record or records with key. In this case, id is sample primary key.
#Path("/employee")
public class EmployeesResource {
static Logger log = LoggerFactory.getLogger(EmployeesResource.class);
#GET
#Produces(MediaType.APPLICATION_JSON)
public List<Employees> index(#BeanParam Employees paramBean) {
EmployeesDao dao = (EmployeesDao) SpringApplicationContext.getBean("employeesDao");
List<Employees> result = dao.read();
System.out.println("Get all employees: size = " + result.size());
return result;
}
#GET
#Path("{id}")
#Produces(MediaType.APPLICATION_JSON)
public Employees show(#PathParam("id") Integer id) {
EmployeesDao dao = (EmployeesDao) SpringApplicationContext.getBean("employeesDao");
System.out.println("Get employees -> id = " + id);
return dao.read(id);
}
#POST
#Consumes(MediaType.APPLICATION_JSON)
public Integer create(Employees obj) {
EmployeesDao dao = (EmployeesDao) SpringApplicationContext.getBean("employeesDao");
return dao.create(obj);
}
#PUT
#Path("{id}")
#Consumes(MediaType.APPLICATION_JSON)
public void update(Employees obj, #PathParam("id") String id) {
EmployeesDao dao = (EmployeesDao) SpringApplicationContext.getBean("employeesDao");
dao.update(obj);
}
#DELETE
#Path("{id}")
public void destroy(#PathParam("id") Integer id) throws Exception {
EmployeesDao dao = (EmployeesDao) SpringApplicationContext.getBean("EmployeesDao");
dao.delete(id);
}
}
GenericDao interface & implementation
Interface ( as is from ibm's post )
According to the post, we can declare dao interface. Then we should implement that interface's methods.
public interface GenericDao<T, PK extends Serializable> {
/** Persist the newInstance object into database */
PK create(T newInstance);
/**
* Retrieve an object that was previously persisted to the database using
* the indicated id as primary key
*/
T read(PK id);
List<T> read();
/** Save changes made to a persistent object. */
void update(T transientObject);
/** Remove an object from persistent storage in the database */
void delete(PK id) throws Exception;
void delete(T persistentObject) throws Exception;
}
Implementation
public class GenericDaoHibernateImpl<T, PK extends Serializable> implements GenericDao<T, PK> {
private Class<T> type;
#Autowired
private SessionFactory sessionFactory;
public SessionFactory getSessionFactory() {
return sessionFactory;
}
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
public GenericDaoHibernateImpl(Class<T> type) {
this.type = type;
}
// Not showing implementations of getSession() and setSessionFactory()
private Session getSession() {
Session session = sessionFactory.getCurrentSession();
return session;
}
#Transactional(readOnly = false, rollbackFor = RuntimeException.class)
public PK create(T o) {
return (PK) getSession().save(o);
}
#Transactional(readOnly = false, rollbackFor = RuntimeException.class)
public void update(T o) {
getSession().update(o);
}
#Transactional(readOnly = true)
public T read(PK id) {
return (T) getSession().get(type, id);
}
#SuppressWarnings("unchecked")
#Transactional(readOnly = true)
public List<T> read() {
return (List<T>) getSession().createCriteria(type).list();
}
#Transactional(readOnly = false, rollbackFor = RuntimeException.class)
public void delete(PK id) {
T o = getSession().load(type, id);
getSession().delete(o);
}
#Transactional(readOnly = false, rollbackFor = RuntimeException.class)
public void delete(T o) {
getSession().delete(o);
}
If you use only simple CRUD operations in the project, you don't need to append any code for SQL operations. For example, you can create another simple SQL tables like divisions_table or personnel_table with using extends GenericDao<Division, Integer> or extends GenericDao<Personnel, Integer>.
EDIT
To instantiate real dao class related with each table, you need to configure applicationContext.xml and beans.
example
<bean id="employeesDao" parent="abstractDao">
<!-- You need to configure the interface for Dao -->
<property name="proxyInterfaces">
<value>jp.gr.java_conf.hangedman.dao.EmployeesDao</value>
</property>
<property name="target">
<bean parent="abstractDaoTarget">
<constructor-arg>
<value>jp.gr.java_conf.hangedman.models.Employees</value>
</constructor-arg>
</bean>
</property>
</bean>
P.S.
You need to remember this article was written a decade ago. And, you should think seriously about which O/R mapper is really good or not. I think O/R mapper is slightly declining now. Instead of Hibernate, you can find MyBatis , JOOQ
This is one way to implement a hibernate centric generic DAO. It provides basic CRUD operations along with simple search but can be extended to include other generic features.
IGenericDAO interface
public interface IGenericDAO<T extends Serializable> {
T findOne(long id);
List<T> findAll();
void create(T entity);
void update(T entity);
void delete(T entity);
void deleteById(long entityId);
public void setClazz(Class<T> clazzToSet);
}
AbstractTemplateDAO
import java.io.Serializable;
import java.util.List;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
public abstract class AbstractHibernateDAO<T extends Serializable> implements IGenericDAO<T> {
private Class<T> clazz;
#Autowired
SessionFactory sessionFactory;
public final void setClazz(Class<T> clazzToSet) {
this.clazz = clazzToSet;
}
#Override
public T findOne(long id) {
return (T) getCurrentSession().get(clazz, id);
}
#Override
public List<T> findAll() {
return getCurrentSession().createQuery("from " + clazz.getName(),clazz).getResultList();
}
#Override
public void create(T entity) {
getCurrentSession().persist(entity);
}
#Override
public void update(T entity) {
getCurrentSession().merge(entity);
}
#Override
public void delete(T entity) {
getCurrentSession().delete(entity);
}
#Override
public void deleteById(long entityId) {
T entity = findOne(entityId);
delete(entity);
}
protected final Session getCurrentSession() {
return sessionFactory.getCurrentSession();
}
}
GenericHiberateDAO
Note: the use of scope prototype here. The spring container creates a new instance of the dao on each request.
#Repository
#Scope(BeanDefinition.SCOPE_PROTOTYPE)
public class GenericHibernateDAO<T extends Serializable> extends AbstractHibernateDAO<T>
implements IGenericDAO<T> {
//
}
Service class
Shows how to use autowire the generic dao in a service class and pass the model class a parameter. Also, do note that this implementation uses #Transactional annotation for spring transaction management.
#Service
public class TestService implements ITestService {
private IGenericDAO<TestModel> dao;
#Autowired
public void setDao(IGenericDAO<TestModel> daoToSet) {
dao = daoToSet;
dao.setClazz(TestModel.class);
}
#Override
#Transactional
public List<TestModel> findAll() {
return dao.findAll();
}
}
App Config
Shows how to set up spring for automatic transaction management using #EnableTransactionManagement
#Configuration
#ComponentScan("com.base-package")
#EnableTransactionManagement
public class AppConfig {
// add hibernate configuration
// add beans
}

Eclipse dao component implement error

I have been working on spring+hibernate+mysql integration recently.For that, I try to build a basic program that adds, edits, deletes and searches students.I have firstly created model class and added necessary JPA annotations:
package com.joseph.model;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
#Entity
public class Student {
#Id
#Column
#GeneratedValue(strategy=GenerationType.AUTO) // for autonumber
private int studentId;
#Column
private String firstname;
#Column
private String lastname;
#Column
private int yearLevel;
public Student(){}
public Student(int studentId, String firstname, String lastname,
int yearLevel) {
super();
this.studentId = studentId;
this.firstname = firstname;
this.lastname = lastname;
this.yearLevel = yearLevel;
}
/* Getters and Setters */
}
Then I constructed DAO interface:
package com.joseph.dao;
import java.util.List;
import com.joseph.model.Student;
public interface StudentDao {
public void add(Student student);
public void edit(Student student);
public void delete(int studentId);
public Student getStudent(int studentId);
public List getAllStudent();
}
To get the necessary data from SQL, I implemented the dao interface as follows:
package com.joseph.dao.impl;
import java.util.List;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import com.joseph.dao.StudentDao;
import com.joseph.model.Student;
#Repository
public class StudentDaoImpl implements StudentDao {
#Autowired
private SessionFactory session;
#Override
public void add(Student student) {
session.getCurrentSession().save(student);
}
#Override
public void edit(Student student) {
session.getCurrentSession().update(student);
}
#Override
public void delete(int studentId) {
session.getCurrentSession().delete(getStudent(studentId));
}
#Override
public Student getStudent(int studentId) {
return (Student)session.getCurrentSession().get(Student.class, studentId);
}
#Override
public List getAllStudent() {
return session.getCurrentSession().createQuery("from Student").list();
}
}
But I have error at add(Student student) method at StudentDaoImpl.java class that says:
Multiple markers at this line
- The method add(Student) of type StudentDaoImpl must override or implement a supertype method
- implements com.joseph.dao.StudentDao.add
This error is similar for all other methods in the same class.
How can I fix this?
You should remove the public from the methods on the Interface:
package com.joseph.dao;
import java.util.List;
import com.joseph.model.Student;
public interface StudentDao {
void add(Student student);
void edit(Student student);
void delete(int studentId);
Student getStudent(int studentId);
List getAllStudent();
}
Your code is 100% working, under my test enviroment (InteliJ, JDK7+), so it is connected with your IDE purely.
Try to restart your IDE or reimport this project.
I could share also some tips:
use Long instead of int, when creating model id's
you don't need to add #Column annotation next to #Id, #Id will do alone
inside your parametrized constructor (Student), you don't need to add super(), compiler will add it automatically, seconsly your upper class is Object, so there is no need for that line :)
using such approach would couse lots of code duplication when you will be using many dao, you could use inheritance here, like so:
Here is example of generic DAO class:
public class GenericDaoImpl <D>{
protected SessionFactory session;
protected Class clazz;
public GenericDaoImpl(SessionFactory session, Class clazz){
this.session = session;
this.clazz = clazz;
}
#Override
public void add(D entity) {
session.getCurrentSession().save(entity);
}
#Override
public void update(D entity) {
session.getCurrentSession().update(entity);
}
#Override
public void remove(Long id) {
session.getCurrentSession().delete(get(id));
}
#Override
public Student get(Long id) {
return (Student)session.getCurrentSession().get(clazz, id);
}
#Override
public List getAll() {
return session.getCurrentSession().createQuery("from " + clazz.getSimpleName()).list();
}
}
To create StudentDao, simply do so:
public interface StudentDao{
void add(Student student);
void update(Student student);
void remove(int id);
Student get(int id);
List getAll();
}
And finally your Dao implementation:
public class StudentDaoImpl extends GenericDaoImpl<Student> implements StudentDao{
#Autowired
public StudentDaoImpl(SessionFactory sessionFactory){
super(sessionFactory, Student.class);
}
}
With this approach you could reuse most of this code in all Dao :) So less code to maintain, easy to use.

Categories