Duvida basica de DAO

Bom, minha duvida é muito basica… eu tenho 3 objetos, persistentes, que se relacionam entre se …

Cidade
Estado
Pais

a cidade tem um método getEstado() … e o estado tem um método getPais()

minha duvida é basica… eu faço 3 DAOs, um para cada Objeto? ou posso fazer um unico DAO para os 3 objetos ??

atualmente tenho CidadeDAO, EstadoDAO, PaisDAO … porem acho que não é necessario…

c for fazer uma unica DAO, qual seria o melhor nome ???

CidadeEstadoPaisDAO ??? ou tem algum q fike melhor ??

Olá amigo!!!

Bom isso depende cara… vc faz a inserção de cidades, Estados e países separadamente???
Se sim, acho que uma parada cada pode ser uma boa…Ou…
Vc pode fazer uma DAO para todos eles… ficaria mais ou menos assim… DAOLocalizacao
Lá vc teria o estado,país,cidade…Ae pra tratar com o BD vc poderia ter uma tabela com o mesmo nome… localizacao… onde vc teria país, estado, cidade…
Espero ter ajudado!!

Você pode usar Generics e criar um DAO reutilizavel e depois criar as especializações do DAO para cada Entidade, com isso fica claro a responsabilidade dos objetos. Se você utilizar algum framework fica fácil fazer isso.
Recomendo você ler o livro Hibernate em Ação, vai tirar muitas dúvidas sobre isso.

Abs

Uso Hibernate (mais estou deixando minha aplicação livre, onde posso a qualquer hora trocar a comunicação com o banco de dados)

em primeiro lugar queria mostrar meu banco para esses objetos em particular,

Eu tenho portanto Interfaces DAO, que tenho q Implementar a depender de qual é minha comunicação com o Banco de Dados, vou mandar o print do eclipse de como ficou a interface depois de juntar os 3 objetos no mesmo DAO

Então eu tenho 1 uma interface IDAOFactory, nela eu tenho a lista de todos os DAOs, e tenho os metodos de Tranzação, assim não preciso saber como converso com o baco de dados…

[code]package br.com.aportepb.dao;

public interface IDAOFactory {
public void beginTransaction();
public void commitTransaction();
public void rollbackTransaction();
public CidadeDAO createCidadeDAO();
public PessoaDAO createPessoaDAO();
}[/code]

Tenho a classe que eu realmente converso que é estatica DAOFactory, e carrega o meu framework que conversa com o banco de dados

[code]package br.com.aportepb.dao;

import br.com.aportepb.dao.hibernate.HibernateDAOFactory;

public class DAOFactory {
private static IDAOFactory minhaDAO = new HibernateDAOFactory();

public static void beginTransaction() {
	minhaDAO.beginTransaction();
}
public static void commitTransaction() {
	minhaDAO.commitTransaction();
}
public static void rollbackTransaction() {
	minhaDAO.rollbackTransaction();
}
public static CidadeDAO createCidadeDAO() {
	return minhaDAO.createCidadeDAO();
}
public static PessoaDAO createPessoaDAO() {
	return minhaDAO.createPessoaDAO();
}

}[/code]

Posteriormente pretendo fazer o carregamento do “IDAOFactory minhaDAO = new HibernateDAOFactory()” atraves de XML podendo ser configurado e modificado, pra rodar com cada tipo de framework pra conversar com o banco de dados…

No meu HibernateDAOFactory eu implemento IDAOFactory, assim, eu posso chamar ele depois estaticamente atravez do DAOFactory, que carrega o Hibernate, neste caso apartir do DAOFacotry eu desconheço que se trata de hibernate

[code]package br.com.aportepb.dao.hibernate;

import br.com.aportepb.dao.*;

public class HibernateDAOFactory implements IDAOFactory {
@Override
public void beginTransaction() {
HibernateHelper.beginTransaction();
}
@Override
public void commitTransaction() {
HibernateHelper.commitTransaction();
}
@Override
public void rollbackTransaction() {
HibernateHelper.rollbackTransaction();
}
@Override
public CidadeDAO createCidadeDAO() {
return new HibernateCidadeDAO();
}
@Override
public PessoaDAO createPessoaDAO() {
return new HibernatePessoaDAO();
}
}[/code]

e cada DAO que eu tenho do hibernate implementa a interface, nas formas do Hibernate … eu troquei pra 1 unico DAO para os 3 objetos

O meu CidadeDAO implementado para o Hibernate ficou assim

[code]package br.com.aportepb.dao.hibernate;

import java.util.List;

import br.com.aportepb.dao.CidadeDAO;
import br.com.aportepb.entidade.Cidade;
import br.com.aportepb.entidade.Estado;
import br.com.aportepb.entidade.Pais;

public class HibernateCidadeDAO implements CidadeDAO {
@Override
public void deleteCidade(Cidade cidade) throws Exception {
HibernateHelper.currentSession()
.delete(cidade);
}
@Override
public void deleteCidade(Integer idDoCidade) throws Exception {
HibernateHelper.currentSession().getNamedQuery(“Cidade.deleteFromId”)
.setInteger(“id”, idDoCidade)
.executeUpdate();
}
@Override
public void deleteEstado(Estado estado) throws Exception {
HibernateHelper.currentSession()
.delete(estado);
}
@Override
public void deleteEstado(Integer idDoEstado) throws Exception {
HibernateHelper.currentSession().getNamedQuery(“Estado.deleteFromId”)
.setInteger(“id”, idDoEstado)
.executeUpdate();
}
@Override
public void deletePais(Pais pais) throws Exception {
HibernateHelper.currentSession()
.delete(pais);
}
@Override
public void deletePais(Integer idDoPais) throws Exception {
HibernateHelper.currentSession().getNamedQuery(“Pais.deleteFromId”)
.setInteger(“id”, idDoPais)
.executeUpdate();
}
@Override
public Cidade getCidade(Integer idDoCidade) throws Exception {
return (Cidade)HibernateHelper.currentSession()
.get(Cidade.class, idDoCidade);
}
@Override
public Cidade getCidade(String nomeDoCidade) throws Exception {
return (Cidade)HibernateHelper.currentSession()
.getNamedQuery(“Cidade.fromNome”)
.setString(“nome”, nomeDoCidade)
.uniqueResult();
}
@Override
public Estado getEstado(Integer idDoEstado) throws Exception {
return (Estado)HibernateHelper.currentSession()
.get(Estado.class, idDoEstado);
}
@Override
public Estado getEstado(String nomeDoEstado) throws Exception {
return (Estado)HibernateHelper.currentSession()
.getNamedQuery(“Estado.fromNome”)
.setString(“nome”, nomeDoEstado)
.uniqueResult();
}
@Override
public Pais getPais(Integer idDoPais) throws Exception {
return (Pais)HibernateHelper.currentSession()
.get(Pais.class, idDoPais);
}
@Override
public Pais getPais(String nomeDoPais) throws Exception {
return (Pais)HibernateHelper.currentSession()
.getNamedQuery(“Pais.fromNome”)
.setString(“nome”, nomeDoPais)
.uniqueResult();
}
@SuppressWarnings(“unchecked”)
@Override
public List getCidades() throws Exception {
return HibernateHelper.currentSession()
.createCriteria(Cidade.class)
.list();
}
@SuppressWarnings(“unchecked”)
@Override
public List getCidades(Estado estado) throws Exception {
return HibernateHelper.currentSession()
.getNamedQuery(“Cidade.fromEstado”)
.setEntity(“estado”, estado)
.list();
}
@SuppressWarnings(“unchecked”)
@Override
public List getCidades(Pais pais) throws Exception {
return HibernateHelper.currentSession()
.getNamedQuery(“Cidade.fromPais”)
.setEntity(“pais”, pais)
.list();
}
@SuppressWarnings(“unchecked”)
@Override
public List getEstados() throws Exception {
return HibernateHelper.currentSession()
.createCriteria(Estado.class)
.list();
}
@SuppressWarnings(“unchecked”)
@Override
public List getEstados(Pais pais) throws Exception {
return HibernateHelper.currentSession()
.getNamedQuery(“Estado.fromPais”)
.setEntity(“pais”, pais)
.list();
}
@SuppressWarnings(“unchecked”)
@Override
public List getPaises() throws Exception {
return HibernateHelper.currentSession()
.createCriteria(Pais.class)
.list();
}
@Override
public void saveCidade(Cidade cidade) throws Exception {

	HibernateHelper.currentSession()
					.save(cidade);
}
@Override
public void saveEstado(Estado estado) throws Exception {
	HibernateHelper.currentSession()
					.save(estado);
}

@Override
public void savePais(Pais pais) throws Exception {
	HibernateHelper.currentSession()
					.save(pais);
}
@Override
public void updateCidade(Cidade cidade) throws Exception {
	HibernateHelper.currentSession()
					.update(cidade);
}
@Override
public void updateEstado(Estado estado) throws Exception {
	HibernateHelper.currentSession()
					.update(estado);
}
@Override
public void updatePais(Pais pais) throws Exception {
	HibernateHelper.currentSession()
					.update(pais);
}
@Override
public void loadCidade(Cidade cidade, Long id) {
	HibernateHelper.currentSession()
						.load(cidade, id);
}

}[/code]

Para quem kizer visualizar o HibernateHelper segue abaixo

Note que nenhum método é publico, pois ninguem fora do pacote br.com.aportepb.dao.hibernate necessita manusiar o HibernateHelper, visto que ele é acessado apenas as classes Hibernate…DAO (por exemplo HibernateCidadeDAO e HibernatePessoaDAO) e HibernateDAOFactory …

Abaixo segue o código do HibernateHelper

[code]package br.com.aportepb.dao.hibernate;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.AnnotationConfiguration;

public class HibernateHelper {
private static final SessionFactory sessionFactory;
@SuppressWarnings(“unchecked”)
private static final ThreadLocal sessionThread = new ThreadLocal();
@SuppressWarnings(“unchecked”)
private static final ThreadLocal transactionThread = new ThreadLocal();

static {
	try {
		sessionFactory = new AnnotationConfiguration().configure()
				.buildSessionFactory();
	} catch (RuntimeException e) {
		e.printStackTrace();
		throw e;
	}
}
@SuppressWarnings("unchecked")
static Session currentSession() {
	if (sessionThread.get() == null) {
		Session session = sessionFactory.openSession();
		sessionThread.set(session);
	}
	return (Session) sessionThread.get();
}
@SuppressWarnings("unchecked")
static void beginTransaction() {
	if (transactionThread.get() == null) {
		Transaction transaction = currentSession().beginTransaction();
		transactionThread.set(transaction);
	}
}
@SuppressWarnings("unchecked")
static void commitTransaction() {
	Transaction transaction = (Transaction) transactionThread.get();
	if (transaction != null && !transaction.wasCommitted()
			&& !transaction.wasRolledBack()) {
		transaction.commit();
		transactionThread.set(null);
	}
	closeSession();
}
@SuppressWarnings("unchecked")
static void rollbackTransaction() {
	Transaction transaction = (Transaction) transactionThread.get();
	if (transaction != null && !transaction.wasCommitted()
			&& !transaction.wasRolledBack()) {
		transaction.rollback();
		transactionThread.set(null);
	}
	closeSession();
}
@SuppressWarnings("unchecked")
private static void closeSession() {
	Session session = (Session) sessionThread.get();
	if (session != null) {
		session.close();
	}
	sessionThread.set(null);
}

}[/code]

Note que o método CloseSession é private, e é chamado apos fazer um rollback ou um commit … sendo assim, é facil a utilizacao, e é fechado sempre no momento correto, e não no meio de tranzações…

Bom acredito que no fim ficou bem facil, vai no post seguinte

Num exemplo pratico de como ficou minha aplicação… eu tenho os meus Objetos Cidade, Estado e Pais … e posso facilmente por exemplo listar as cidade do pais brasil

[code]//…
CidadeDAO dao = DAOFactory.createCidadeDAO();
Pais brasil = dao.getPais(“Brazil”);

//Neste caso cidadesDoBrasil vai ser uma lista de objetos com todas as cidades que pertecem ao brasil
List cidadesDoBrasil = dao.getCidades(brasil);

/** aqui abaixo mostra como salvar um estado no banco de dados */
Estado paraiba = new Estado(“Paraíba”,brasil);
DAOFactory.beginTransaction();
try {
dao.saveEstado(paraiba);
DAOFactory.commitTransaction();
} catch (Exception ex) {
DAOFactory.rollbackTransaction();
ex.printStackTrace();
}[/code]

Note que eu não precisei saber que se trata de hibernate, ou algo assim, mesmo para fazer Transaction…

eu apenas converso com DAOFactory… esta é minha porta de comunicação com o banco de dados, e no DAOFactory, eu posso trocar depois se preciso o Hibernate por outro framework se for necessario

Se possivil, gostaria de opiniões c esta OK assim

Acredito que pela questão das modificações futuras que você mesmo propõe, é mais interessante ter as DAOs separadas…
O último sistema que meus colegas e eu desenvolvemos como projeto da faculdade tem todas as DAO separadas. De maneira que posso modificar qualquer campo a qualquer tempo…

[quote=Balena]Acredito que pela questão das modificações futuras que você mesmo propõe, é mais interessante ter as DAOs separadas…
O último sistema que meus colegas e eu desenvolvemos como projeto da faculdade tem todas as DAO separadas. De maneira que posso modificar qualquer campo a qualquer tempo…[/quote]

Os campos estão disponiveis para ser modifcados a partir dos objetos, mesmo…

Eu so juntei 3 Entidades na mesma dão, pois ela estão intimamente ligadas, Pais, Estado e Cidade … então posso pegar minha dão

CidadeDAO dao = DAOFactory.createCidadeDAO();

então atravez de um unico DAO eu posso fazer tudo com os 3 objetos… Pais, Estado e Cidade … porem tenho acesso a qualquer campo, e posso modificar tudo…

por exemplo …

//Supondo que o estado "Paraíba" que esta no banco com o código 2, tenha seu nome escrito errado "Paraiiba", e deseje alterar isso Estado estado = dao.getEstado(2); estado.setNome("Paraíba"); DAOFactory.beginTransaction(); try { dao.updateEstado(paraiba); DAOFactory.commitTransaction(); } catch (Exception ex) { DAOFactory.rollbackTransaction(); System.out.println("Exceção iniciou em: " + ex); throw ex; }

Da mesma forma varias outras coisas são suportadas, como:

  • adcionar um: pais, estado ou cidade
  • atualizar um: pais, estado ou cidade
  • apagar um: pais, estado ou cidade
  • pegar lista de paises
  • pegar lista de estados: Totais ou por pais
  • pegar lista de cidades: Totais, por estado ou por pais

Entre diversas outras operações disponiveis pela inteface CidadeDAO, e sempre que necessario posso implementar mais …
Enfim, o fato de juntar não limita os campos que tenho acesso, mais apenas junta em uma mesma DAO varias operações…

o meu problema estava sendo pricipalmente no descrito abaixo

[code] Pais pais = new Pais(“Brasil”);
Estado estado = new Estado(“Paraíba”,pais);
Cidade cidade = new Cidade(“João Pessoa”,estado);

	CidadeDAO dao = DAOFactory.createCidadeDAO();
	
	DAOFactory.beginTransaction();
	try {
		dao.savePais(pais);
		dao.saveEstado(estado);
		dao.saveCidade(cidade);
		DAOFactory.commitTransaction();
	} catch (Exception ex) {
		DAOFactory.rollbackTransaction();
		ex.printStackTrace();
	}[/code]

Como eu queria criar os 3, tanto o pais, como a cidade e o estado, eu estava precisando crair 3 DAO pq tinha um dao parar cada Entity … colocando todas no mesmo DAO, acredito que simplificou meu processo

Se alguem puder me ajudar, estou tentando montar um UML para esse sistema ai no link abaixo

http://www.guj.com.br/posts/list/111957.java

[quote=Lavieri]Bom, minha duvida é muito basica… eu tenho 3 objetos, persistentes, que se relacionam entre se …

Cidade
Estado
Pais

a cidade tem um método getEstado() … e o estado tem um método getPais()

minha duvida é basica… eu faço 3 DAOs, um para cada Objeto? ou posso fazer um unico DAO para os 3 objetos ??
[/quote]

Vc precisa de 3 interfaces , mas não necessariamente de 3 objetos ou 3 classes.
Tudo depende de como o seu DAO é. Se ele usa JDBC directo ou outra coisa.

Se vc me responder que vai usar hibernate então já lhe digo que isso não é um DAO que está tentando criar.
Nesse caso eu recomendo que vc cria uma classe abstract com genéricos e uso o padrão registry. Depois vc implementa 3 classes uma para cada entidade que herdam dessa classe abstract.

[quote=sergiotaborda][quote=Lavieri]Bom, minha duvida é muito basica… eu tenho 3 objetos, persistentes, que se relacionam entre se …

Cidade
Estado
Pais

a cidade tem um método getEstado() … e o estado tem um método getPais()

minha duvida é basica… eu faço 3 DAOs, um para cada Objeto? ou posso fazer um unico DAO para os 3 objetos ??
[/quote]

Vc precisa de 3 interfaces , mas não necessariamente de 3 objetos ou 3 classes.
Tudo depende de como o seu DAO é. Se ele usa JDBC directo ou outra coisa.

Se vc me responder que vai usar hibernate então já lhe digo que isso não é um DAO que está tentando criar.
Nesse caso eu recomendo que vc cria uma classe abstract com genéricos e uso o padrão registry. Depois vc implementa 3 classes uma para cada entidade que herdam dessa classe abstract.[/quote]

Na verdade eu não quero amarrar meu sistema ao hibernate, pois quero poder migrar livrimente… eu atualmente estou persistindo os dados via Hibernate, pois é o modo mais pratico que conheço…

Eu me relaciono diretamente apenas com a classe DAOFactory … só com ela… nela tenho metodos de tranzação como:
DAOFactory.beginTransaction(); DAOFactory.commitTransaction(); e DAOFactory.rollbackTransaction();

é atravez dele que chamo meus DAO … e estes DAO são sempre enviados via Interface pre definida… como por exemplo

/**CidadeDAO = Interface que contém todos os metodos pra tratar com os objetos Cidade, Estado e Pais Apesar deu estar tratando de Hibernate para o meu caso, posso trocar o modo de conversar com meus dados, e esta interface vai continuar valida*/ CidadeDAO dao = DAOFactory.createCidadeDAO();

O modo pra escolher como conversar com o banco de dados é feito implementando uma interface que eu criei tb… IDAOFactory, essa interface contem todos os métodos para criar as DAOs como o createCidadeDAO() além de conter todos os metodos de Transaction como o commitTransaction() entre outros…

Minha calsse DAOFactory, tem 1 campo statico IDAOFactory … este campo é usado pra chamar os metodos da classe implementada de IDAOFactory estaticamente… por exemplo, atualmente eu to usando

Na classe DAOFactory

DAOFactory.minhaDAOFactory = new HibernateDAOFactory(); //... public CidadeDAO createCidadeDAO() { return minhaDAOFactory.createCidadeDAO(); }

onde o modo deu criar uma interface CidadeDAO é

Na classe HibernateDAOFactory

//Onde a classe HibernateCidadeDAO implementa CidadeDAO public CidadeDAO createCidadeDAO() { return new HibernateCidadeDAO(); }

Realmente vc acha inviavel fazer os DAO usando Hibernate ?? qual seria o PQ ? c vc puder conversar via MSN pra explicar melhor alguns pontos obscuros no meu conceito eu posso agradecer tb ^^ … obrigado pela atenção

[quote=Lavieri]
Realmente vc acha inviavel fazer os DAO usando Hibernate ?? qual seria o PQ ? c vc puder conversar via MSN pra explicar melhor alguns pontos obscuros no meu conceito eu posso agradecer tb ^^ … obrigado pela atenção[/quote]

Eu não acho inviável. Acho um absurdo e uma perca de tempo.

Repare que o Hibernate é genérico. Ele funciona diretamente com qualquer classe. Ai vc vai e cria um monte de DAO
para o encapsular. A capacidade do Hibernate é muito maior que a de um DAO ( o Hibernate implementa o padrão Domain Store)
Vc acaba tendo N objetos quando poderia ter só um. Repare que o métodos save , update etc… são iguais para todos os DAOs e isso é por causa do design do hibernate.

Vc acha que está criando uma arquitetura independente da persistência só pq usa o DAO. Mentira.
Quer a prova ? Implemente uma DAOFactory diferente que não use Hibernate. A sua aplicação ainda funciona ?