2
\$\begingroup\$

Regarding re-usability, is this OK? What might go wrong? What would be a better design? Performance-related issues and any other comments are welcome.

package sample.library.dao.util;

import java.io.Serializable;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.transaction.annotation.Transactional;

/** 
 * @author mulean
 *
 */
 @Transactional(value = "transactionManager", timeout = 30,  
 rollbackFor = java.lang.Exception.class)
 public class DAOUtil {

@Autowired
HibernateTemplate template; 

public  <T> T updateData(T t){
    template.update(t);
    return t;
}
public  <T> T delete(T t){
    template.delete(t);
    return t;
}

public  <T> Boolean save(T t){
    boolean success = false;
    try{
        template.saveOrUpdate(t);
        success = true;
    }catch(Exception e){
        success = false;
        return success;
    }
        return success;
}
@SuppressWarnings("unchecked")
public  <T> List<T> listData(String className){
    List<T> items = null;
    items = template.find("from "+className.toUpperCase());
    return items;
}
}
\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

What about having generic abstract dao class which will contain these methods? You will most likely have to create some concrete dao classes anyway to have specific methods. We are using this approach in our projects (behind JPA facade)

public abstract class AbstractJpaDao<T extends AbstractEntity> implements GenericDao<T> {

    @PersistenceContext
    protected EntityManager entityManager;

    protected final Class<T> entityClass;

    public AbstractJpaDao(Class<T> entityClass) {
        this.entityClass = entityClass;
    }

    @Override
    public T get(Serializable id) {
        Assert.notNull(id, "Entity ID cannot be null");
        return entityManager.find(entityClass, id);
    }

    @Override
    public List<T> findAll() {
        CriteriaBuilder builder = entityManager.getCriteriaBuilder();
        CriteriaQuery<T> query = builder.createQuery(entityClass);
        Root<T> root = query.from(entityClass);
        query.select(root);
        return entityManager.createQuery(query).getResultList();
    }

EDIT Also do not put @Transactional on your DAO classes but on Services. Service method describes unit of work which should be done whole or rollbacked. Consider this simple code

public void save() {
 dao1.delete(entity1);
 dao2.delete(entity2);
}

When second dao fails to delete and you have transactional daos not service, the first entity is lost.

And you save method should not return boolean, but let bubble the exception up into the service layer and let service handle the exception.

\$\endgroup\$
3
  • \$\begingroup\$ That's right I should consider that as an option but i would want more explanation, why you don't use it as a helper/utility class and work around the "extends" thing? I also noticed a couple of things safe from your approach. making sure that required information to get half way of a successful transaction, by asserting at least that the id id not null, shows care about details, I will absolutely keep that in mind, thanks. \$\endgroup\$
    – LeandreM
    Oct 15, 2013 at 13:36
  • \$\begingroup\$ As i said you will most likely end up with lot of specific dao classes. And it is unnecessary duplication to have methods like save, update, get in all daos. And all of them would only call this util class. \$\endgroup\$
    – DominikM
    Oct 15, 2013 at 13:46
  • \$\begingroup\$ I extended the answer. Take a look. \$\endgroup\$
    – DominikM
    Oct 15, 2013 at 13:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.