Caros,
Estou implementando um DAO Genérico, porém tenho algumas dúvidas que não encontrei, nem no fórum nem pela web.
Bom, li estes links:
http://www.hibernate.org/328.html
http://www-128.ibm.com/developerworks/java/library/j-genericdao.html
http://aujava.wordpress.com/2006/08/09/generic-dao-and-more/
http://www.dhptech.com/node/18
http://www.java2s.com/Code/Java/Hibernate/GenericDaoCreate.htm
e fiz uma implementação de um DAO Genérico, que vos passo:
//AbstractDAO.java
package com.marcosperon.dao;
import java.util.List;
public interface AbstractDAO <DomainObject, KeyType> {
public DomainObject load(KeyType id) throws Exception;
public void update(DomainObject object) throws Exception;
public void delete(DomainObject object) throws Exception;
public void save(DomainObject object) throws Exception;
public void deleteById(KeyType id);
public List<DomainObject> getList();
public void deleteAll();
public int count();
}
e uma implementação usando hibernate:
//HibernateAbstractDAO.java
package com.marcosperon.dao.hb;
import com.marcosperon.dao.AbstractDAO;
import com.marcosperon.hb.HibernateUtility;
import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;
import org.hibernate.Session;
/**
*
* @author Marcos Peron
*/
public abstract class HibernateAbstractDAO<T extends Serializable, KeyType extends Serializable>
implements AbstractDAO<T, KeyType> {
@SuppressWarnings(value = "unchecked")
protected Class<T> domainClass = getDomainClass();
public HibernateAbstractDAO() {
}
@SuppressWarnings(value = "unchecked")
public T load(KeyType id) {
return ((T)getSession().load(domainClass, id));
}
public void update(T obj) {
getSession().update(obj);
}
public void save(T obj) {
getSession().save(obj);
}
public void saveOrUpdate(T obj) {
HibernateUtility.beginTransaction();
getSession().saveOrUpdate(obj);
HibernateUtility.commitTransaction();
}
public void delete(T t) {
getSession().delete(t);
}
@SuppressWarnings(value = "unchecked")
public List<T> getList() {
Session s = getSession();
return(s.createCriteria(domainClass).list());
}
public void deleteById(KeyType id) {
Object obj = load(id);
getSession().delete(obj);
}
public void deleteAll() {
getSession().createQuery("delete " + domainClass.getName()).executeUpdate();
}
public int count() {
List list = getSession().createQuery("select count(*) from " + domainClass.getName() + " x").list();
Integer count = (Integer) list.get(0);
return(count.intValue());
}
protected Session getSession() {
return(HibernateUtility.getSession());
}
@SuppressWarnings(value = "unchecked")
protected Class getDomainClass() {
if (domainClass == null) {
ParameterizedType thisType = (ParameterizedType) getClass().getGenericSuperclass();
domainClass = (Class) thisType.getActualTypeArguments()[0];
}
return domainClass;
}
}
Bom, se eu tiver então um Bean chamado de Bean:
//Bean.java
package com.marcosperon.beans;
import java.io.Serializable;
public class Bean implements Serializable, Comparable<Long> {
private static final long serialVersionUID = 1;
private Long id;
public Bean() {
//hello do something here
}
private void setId(Long id) {
this.id = id;
}
public Long getId() {
return id;
}
public int compareTo(Long obj) {
//...
}
public boolean equals(Object obj) {
//...
}
public int hashCode() {
//...
}
}
e o Bean Person que estende pessoa:
//Person.java
package com.marcosperon.beans;
public class Person extends Bean {
private String firstName;
private String lastName;
private String personId;
private boolean active = false;
public Person() {
super();
}
public boolean isActive() {
return active;
}
public void setActive(boolean active) {
this.active = active;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public void setName(String name) {
if (name == null) {
return;
}
if ("".equals(name)) {
return;
}
int iSpacePosition = name.lastIndexOf(" ");
if (iSpacePosition > -1) {
setFirstName(name.substring(0, iSpacePosition - 1));
setLastName(lastName = name.substring(iSpacePosition + 1));
} else {
setFirstName(name);
setLastName("");
}
}
public String getName() {
StringBuffer fullName = new StringBuffer(getFirstName().length() + getLastName().length() + 1);
fullName.append(getFirstName());
if (!("".equals(getLastName()))) {
fullName.append(" ");
fullName.append(getLastName());
}
return fullName.toString();
}
public String getPersonId() {
return personId;
}
public void setPersonId(String personId) {
this.personId = personId;
}
}
Bom, agora implementando um DAO para cada um, usando da herança, eu faria:
//BeanDAO.java
package com.marcosperon.dao;
import com.marcosperon.beans.Bean;
public interface BeanDAO<DomainObject> extends AbstractDAO<DomainObject, Long> {
}
//PersonDAO.java
public interface PersonDAO<Person> extends BeanDAO<Person> {
public List getByName(String name);
}
Ok, até ai tudo bem. isso funciona maravilhosamente BEM.
Porém, se eu criasse outro Bean que estende Person, como Student, e eu quisesse Herdar também os dados da interface PersonDAO, como faria?
Lembrando que eu já passei o tipo para o Generics acima ().
Bom, eu poderia na interface PersonDAO, fazer assim:
//PersonDAO.java
public interface PersonDAO<T extends Person> extends BeanDAO<T> {
public List getByName(String name);
}
e a interface do Student
//StudentDAO.java
public interface StudentDAO<T extends Person> extends PersonDAO<T> {
public List getGroups();
}
E na inicialização a minha implementação criar StudentDAO pd = new StudentDAOImpl();
mas quando rodo, essa parte da implementação do hibernate dá erro:
@SuppressWarnings(value = "unchecked")
protected Class getDomainClass() {
if (domainClass == null) {
ParameterizedType thisType = (ParameterizedType) getClass().getGenericSuperclass();
domainClass = (Class) thisType.getActualTypeArguments()[0];
}
return domainClass;
}
Porém, se eu fizesse a interface de Student já vir tipada o Generics, ia funcionar numa boa.
Então minha dúvida é essa, como fazer para não perder a possibilidade de herdar também os DAOs Genéricos e pais, sem ter que determinar um tipo no ultimo DAO.
Será que me fiz entender?
Se algúem tiver alguma luz…
Obrigado
Abraços
