my question is: Are your service layer bound to tecnology you use?
For example, if you using hibernate, you put into your service layer some hql-queries or criteria-queries that are only hibernate features or you call simply DAO(and dao has hibernate implementation, and maybe jdbc implementation etc..) ?
I have some trouble to build an efficent layered architecture for my software.
EDIT This is a simple service...i think it's a service... without bound to tecnlogy i using (hibernate)
@Repository
public class PersonHibernateDAO implements PersonDAO {
@Autowired
SessionFactory sessionFactory;
... dao crud operations(implementation of PersonDAO interface) using sessionfactory ...
//and some hibernate features methods
public Person findByCriteria(Criterion criterion){
// code
}
}
@Service
public class PersonService {
@Autowired
private PersonDAO personDao;
@Autowired
private AccessDAO accessDao;
@Transactional
public boolean hasPermission(String username, String accessCode){
Person p=personDao.findByUsername(username);
Access a=accessDao.findByCode(accessCode);
... etc ...
}
}
And this is a service with use Dao implementation
@Service
public class PersonService {
@Autowired
private PersonDAO personDao;
@Autowired
private AccessDAO accessDao;
@Transactional
public boolean hasPermission(String username, String password){
Person p=((PersonHibernateDao)personDao).findByCriteria(Restrictions.eq("username", username);
... etc ...
}
}
Wich of these two approach is right?
EDIT2
So, to summarize what I understood:
// BASE DAO INTERFACE
public interface DAOInterface<EntityClass, IDType extends Serializable> {
EntityClass get(IDType id);
EntityClass findById(IDType id);
EntityClass save(EntityClass entity);
EntityClass update(EntityClass entity);
void delete(EntityClass entity);
}
// AN HIBERNATE IMPLEMENTATION
public abstract class HibernateDAO<EntityClass, IDType extends Serializable> implements DAOInterface<EntityClass, IDType> {
@Autowired
private SessionFactory sessionFactory;
public void setSessionFactory(SessionFactory sessionFactory){
this.sessionFactory=sessionFactory;
}
public void getSessionFactory(){
return this.sessionFactory;
}
// Implements all DAOInterface method using sessionFactory
}
// PERSON DAO INTERFACE
public interface PersonDAO extends DAOInterface<Person, Long>{
Person findByName(String name, String surname);
List<Person> getInAgeRange(int year1, int year2);
}
// PERSON HIBERNATE DAO IMPLEMENTATION
public PersonHDAO extends HibernateDAO<Person, Long> implements PersonDAO{
// Implements the methods of PersonDAO interface using sessionFactory
}
@Service
public class PersonService {
//spring inject the correct DAO by its xml config(in this case PersonHDAO
@Autowired
private PersonDAO personDAO;
// spring manage the transaction
@Transactional
public List<Person> getInAgeRange(int year1, int year2){
return personDAO.getInAgeRange(year1, year2);
}
}
// NOW... HOW USE IT
//let's assume i have a button, pressing it a table will be populated with all persons in age range
private void actionPerfom(ActionEvent e){
List<Person> list=personService.getInAgeRange(age1Spinner.getValue(), age2Spinner.getValue());
//Load a table with list
}
Sorry for this wall of text, maybe can be useful for others i hope, im go in the right direction? My service layer need an interface? Is all corectly layered? I need a control layer too?
Thanks.
My suggestion:
for larger projects, use a dedicated, interface based DAO layer. Don't let your service layer know anything about the underlying persistence technology. Use Hibernate / JPA / JDBC / JDO / whatever only in the DAO layer.
for smaller projects it may be okay to have a service layer only (especially given the fact that both Hibernate Session
and JPA EntityManager
expose most standard DAO behavior out of the box.
Basic rule of thumb: if you're making a technology change, make sure you only need to change one layer of your application
Update: here's a sample DAO interface. Your service layer would only code against this interface, and the implementation would do the session / entityManager / jdbc calls without the service layer needing to know.
public interface CustomerDao extends CommonDao<Customer>{
Customer getCustomerByEmail(String emailAddress);
List<Customer> getCustomersWithinAgeRange(int lowerBound, int upperBound);
}
The key: in your service layer, specify your dependencies interface-based, i.e.
private CustomerDao customerDao;
public void setCustomerDao(CustomerDao customerDao){
this.customerDao = customerDao;
}
instead of
// this is horrible, it ties the service layer to implementation
// details of the dao layer
private HibernateCustomerDaoImpl customerDao;
public void setCustomerDao(HibernateCustomerDaoImpl customerDao){
this.customerDao = customerDao;
}