[EJB] - Design Pattern e boas práticas

Boa tarde pessoal!

Por gentileza, eu estou com uma dúvida cruel e gostaria da ajuda de vocês.

1ª Parte
Eu estou utlizando EJB no meu TCC. O projeto consiste em Gerenciar os setores de Agricultura, Pesca e Pecuária, pois bem, eu criei 3 módulos: Agricultura, Pesca e Pecuária e os deixei com a responsabilidade de Persistência, apenas.

Eu estou utlizando JPA, portanto, cada CRUD, e vale lembrar que eu utilizei Generics, jah que os meus módulos não estão com os Entities, possui um EntityManager. - Estou utilizando GLASSFISH, pool de conexões, etc…

2ª parte
Eu criei um Web Project que conterá, os meus MB’s (JSF 2), os Entities, validações, conversões, etc. Ou seja, nas minhas classes JSF, eu vou injetar um @EJB, para acessar os meus métodos de persistência, que como eu jah disse, estarão contidos nos respectivos módulos EJB.

Eu gostaria de saber de vocês, se esse raciocínio esta correto, em termos de padrão e arquitetura, utilizando-se EJB? E se eh uma boa pratica deixar os módulos apenas com a responsabilidade de tratar a parte da persistência se pensarmos em escalabilidade e reaproveitamento?

Apenas com a intenção de ilustrar a minha dúvida:

EJB ========= EJB ====== EJB ======== Web Project
Agricultura === Pesca ===== Pecuaria ==== APP
CRUD ======= CRUD ====== CRUD ====== Entities+JSF

Eu não sei se eu fui muito claro na minha questão, qualquer palpite eh bem vindo.

Desde jah, eu agradeço!

[]'s

uma coisa que eu faço é deixar as entidades e o arquivo de configuração do jpa (persistence.xml) em um outro projeto a parte… os outros referenciando este.

Para os cruds enxergarem as entidades do jpa você fez como? deixou seus projetos de ejb referenciando o de web ?

[quote=maior_abandonado]uma coisa que eu faço é deixar as entidades e o arquivo de configuração do jpa (persistence.xml) em um outro projeto a parte… os outros referenciando este.

Para os cruds enxergarem as entidades do jpa você fez como? deixou seus projetos de ejb referenciando o de web ?[/quote]

Oi amigo,

Eu deixei as entidades e o persistence.xml do JPA no meu projeto web. Nos cruds, que estão nos módulos, eu utilizei generics :(. O que ce acha?

Valeu a força!
[]'s

Um dos módulos:

[code]package br.com.sisgappe.sessionbeans.impl;

import br.com.sisgappe.sessionbeans.IAgricultura;

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

import javax.ejb.Local;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import javax.persistence.criteria.CriteriaQuery;

@SuppressWarnings(“rawtypes”)
@Stateless
@Local({ IAgricultura.class })
public class AgriculturaBeanImpl<T, ID extends Serializable> implements
IAgricultura {

@PersistenceContext
private EntityManager entityManager;

public EntityManager getEntityManager() {
	return entityManager;
}

public void setEntityManager(EntityManager entityManager) {
	this.entityManager = entityManager;
}

@SuppressWarnings("unchecked")
@Override
public List&lt;T&gt; listAll(Object entity) {
	Query query = this.getEntityManager().createQuery(
			"from " + entity.getClass().getName());
	return query.getResultList();
}

@Override
public void save(Object entity) {
	this.getEntityManager().persist(entity);
}

@Override
public List&lt;T&gt; findByCriteria(CriteriaQuery... criterion) {
	// TODO Auto-generated method stub
	return null;
}

@SuppressWarnings("unchecked")
@Override
public List&lt;T&gt; findBySQL(String sql) {
	Query query = this.getEntityManager().createNativeQuery(sql);
	return query.getResultList();
}

@Override
public void update(Object entity) {
	this.getEntityManager().merge(entity);
}

@Override
public Object findById(Object entity, Serializable id) {
	return this.getEntityManager().getReference(entity.getClass(), id);

}

@Override
public void delete(Object entity, Serializable id) {
	this.findById(entity, id);

}

}
[/code]

cara,

um padrão bacana, que vc pode seguir seria o MVC, aonde ficaria assim
Model - camada responsavel pela sua regra de negocio, enttidade e persistencia. eu utilizo em meus projetos patterns, DAO (aonde eu faço um classe basica com todos as necessidades para a persistencia), Facade (responsavel pela regra de negocio), entity (classe que espelham seu banco e contem as anotações para mapeamento do JPA)
View - camada aonde possui todas seus xhtml, css, js, imagens e etc.
Controller - camada responsavel por fazer a ligação da sua camada de visão com a camada de model, nela se faz as validações, conversões e etc.

espero ter te ajudado

t+

[quote=alissonvla]cara,

um padrão bacana, que vc pode seguir seria o MVC, aonde ficaria assim
Model - camada responsavel pela sua regra de negocio, enttidade e persistencia. eu utilizo em meus projetos patterns, DAO (aonde eu faço um classe basica com todos as necessidades para a persistencia), Facade (responsavel pela regra de negocio), entity (classe que espelham seu banco e contem as anotações para mapeamento do JPA)
View - camada aonde possui todas seus xhtml, css, js, imagens e etc.
Controller - camada responsavel por fazer a ligação da sua camada de visão com a camada de model, nela se faz as validações, conversões e etc.

espero ter te ajudado

t+[/quote]

Beleza, alissonvla?

Pelo que eu estou entendendo os módulos EJB substituíram o DAO, portanto, vocês acham que o EJB e o MVC podem andar de mãos dadas? Ou não, eu teria que sacar fora o EJB, se eu quisesse adotar o MVC?

[]'s

cara, foi mau, esqueci de te falar em cima,

seu facade seria o ejb, vc teria algo assim

xhtml - controller (@ManagedBean) - facade (@Ejb) - DAO (vc injeta o @@PersistenceContext uma unica vez na classe base)

segue um exemplo do base dao

package br.com.bingo.dao;

import java.util.Date;
import java.util.HashMap;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import javax.persistence.TemporalType;

import org.hibernate.Session;

public abstract class BaseDAO<T> {
	
	@PersistenceContext
	private EntityManager entityManager;
	
	protected BaseDAO(){
	}
	
	public void inserir(T object) {
		entityManager.persist(object);
		entityManager.flush();
	}

	public T alterar(T object) {
		object = entityManager.merge(object);
		entityManager.flush();
		
		return object;
	}
	
	public void excluir(Class<T> classe, Object id) {
		entityManager.remove(entityManager.find(classe, id));
		entityManager.flush();
	}
	
	@SuppressWarnings("rawtypes")
	protected void excluirClausulaIN(String sql, HashMap<String, Object> parametros){
		Session session = (Session) entityManager.getDelegate();
		
		org.hibernate.Query query = session.createQuery(sql);
		
		if(parametros != null && !parametros.keySet().isEmpty()){
			for(String parametro : parametros.keySet()){
				if(parametros.get(parametro) instanceof List){
					query.setParameterList(parametro, (List)parametros.get(parametro));
				}else{
					query.setParameter(parametro, parametros.get(parametro));
				}
			}
		}
		
		query.executeUpdate();
	}

	public void executeNativeQuery(Class<T> classe, String sql, HashMap<String, Object> parametros) {
		Query query = entityManager.createNativeQuery(sql, classe);
		
		if(parametros != null && !parametros.keySet().isEmpty()){
			for(String parametro : parametros.keySet()){
				query.setParameter(parametro, parametros.get(parametro));
			}
		}
		
		query.executeUpdate();
	}
	
	public T pesquisar(Class<T> classe, Object id) {
		return (T) entityManager.find(classe, id);
	}
	
	@SuppressWarnings("unchecked")
	protected List<T> pesquisarEntidades(String sql, HashMap<String, Object> parametros, boolean todos, int primeiroResultado, int maxResultado){
		Query query = entityManager.createQuery(sql);

		if(parametros != null && !parametros.keySet().isEmpty()){
			for(String parametro : parametros.keySet()){
				if(parametros.get(parametro) instanceof Date){
					query.setParameter(parametro, (Date)parametros.get(parametro), TemporalType.DATE);
				}else{
					query.setParameter(parametro, parametros.get(parametro));
				}
			}
		}
		
		if (!todos) {
			query.setMaxResults(maxResultado);
			query.setFirstResult(primeiroResultado);
		}
		return query.getResultList();
	}
	
	@SuppressWarnings({ "rawtypes", "unchecked" })
	protected List<T> pesquisarEntidadesClausulaIN(String sql, HashMap<String, Object> parametros, boolean todos, int primeiroResultado, int maxResultado){
		Session session = (Session) entityManager.getDelegate();
		
		org.hibernate.Query query = session.createQuery(sql);
		
		if(parametros != null && !parametros.keySet().isEmpty()){
			for(String parametro : parametros.keySet()){
				if(parametros.get(parametro) instanceof List){
					query.setParameterList(parametro, (List)parametros.get(parametro));
				}else{
					query.setParameter(parametro, parametros.get(parametro));
				}
			}
		}
		
		if (!todos) {
			query.setMaxResults(maxResultado);
			query.setFirstResult(primeiroResultado);
		}
		return query.list();
	}
	
	protected List<T> pesquisarEntidades(String sql, HashMap<String, Object> parametros){
		return pesquisarEntidades(sql, parametros, true, 0, 0);
	}
	
	protected List<T> pesquisarEntidades(String sql){
		return pesquisarEntidades(sql, null, true, 0, 0);
	}
	
	protected List<T> pesquisarEntidadesClausulaIN(String sql, HashMap<String, Object> parametros){
		return pesquisarEntidadesClausulaIN(sql, parametros, true, 0, 0);
	}
	
	protected List<T> pesquisarEntidadesClausulaIN(String sql){
		return pesquisarEntidadesClausulaIN(sql, null, true, 0, 0);
	}
	
	@SuppressWarnings("unchecked")
	protected List<T> pesquisarEntidadesNativeQuery(Class<T> classe, String sql, HashMap<String, Object> parametros, boolean todos, int primeiroResultado, int maxResultado){
		Query query = entityManager.createNativeQuery(sql, classe);
		
		if(parametros != null && !parametros.keySet().isEmpty()){
			for(String parametro : parametros.keySet()){
				query.setParameter(parametro, parametros.get(parametro));
			}
		}
		
		if (!todos) {
			query.setMaxResults(maxResultado);
			query.setFirstResult(primeiroResultado);
		}
		return query.getResultList();
	}
	
	@SuppressWarnings("unchecked")
	protected T pesquisarEntidadeNativeQuery(Class<T> classe, String sql, HashMap<String, Object> parametros){
		try {
			Query query = entityManager.createNativeQuery(sql, classe);
			
			if(parametros != null && !parametros.keySet().isEmpty()){
				for(String parametro : parametros.keySet()){
					if(parametros.get(parametro) instanceof Date){
						query.setParameter(parametro, (Date)parametros.get(parametro), TemporalType.TIMESTAMP);
					}else{
						query.setParameter(parametro, parametros.get(parametro));
					}
				}
			}
			
			return (T) query.getSingleResult();
		} catch (Exception e) {
			return null;
		}
	}
	
	
	@SuppressWarnings("unchecked")
	protected List<T> pesquisarEntidadesNativeQuery(String sql, HashMap<String, Object> parametros, boolean todos, int primeiroResultado, int maxResultado){
		Query query = entityManager.createNativeQuery(sql);
		
		if(parametros != null && !parametros.keySet().isEmpty()){
			for(String parametro : parametros.keySet()){
				query.setParameter(parametro, parametros.get(parametro));
			}
		}
		
		if (!todos) {
			query.setMaxResults(maxResultado);
			query.setFirstResult(primeiroResultado);
		}
		return query.getResultList();
	}
	
	@SuppressWarnings("unchecked")
	protected T pesquisarEntidade(String sql, HashMap<String, Object> parametros) throws NoResultException{
		try{
			Query query = entityManager.createQuery(sql);
			
			if(!parametros.keySet().isEmpty()){
				for(String parametro : parametros.keySet()){
					if(parametros.get(parametro) instanceof Date){
						query.setParameter(parametro, (Date)parametros.get(parametro), TemporalType.TIMESTAMP);
					}else{
						query.setParameter(parametro, parametros.get(parametro));
					}
				}
			}
			
			return (T) query.getSingleResult();
		}catch(Exception e){
			return null;
		}
	}
}

t+

alissonvla,

Desculpe se eu estou sendo chato. Me corrija se eu estiver errado, por favor.

Eu terei apenas um DAO na minha aplicação e N Session Beans, que no caso, serão os meus Facades, certo?

Por exemplo, eu terei 3 sessions beans e poderei injetar em cada um deles o meu DAO, como foi feito aqui, correto?

Soh mais uma dúvida, como eu havia comentado mais acima, as minha classes de entidade do JPA, bem como, o meu arquivo persistence.xml, estão no meu Projeto Web, isso estaria correto, de acordo com seu raciocínio posto ai?

Mais uma vez, obrigado!

[]'s

vc vai ter um DAO, por entidade que vc que vc necessite persistir.
vc vai ter um Facade, por entidade, como se diz “Forte”, no seu sistema.
vc vai ter um Controller, por caso de uso.

dessa forma fica bem divido e facil de se trabalhar.

segue uma classe dao que utiliza a classe basedao que eu te passei.

como vc vai ta usando Jee 6 vc pode fazer tudo no projeto web, ficou facilitou, nao necessita ter varios projetos.

package br.com.bingo.dao;

import java.util.HashMap;
import java.util.List;

import br.com.bingo.entity.Usuario;

public class UsuarioDAO extends BaseDAO<Usuario> {
	
	protected UsuarioDAO() {
		
	}
	
	public List<Usuario> pesquisarUsuarios(Usuario usuario){
		HashMap<String, Object> parametros = new HashMap<String, Object>();
		StringBuilder query = new StringBuilder();
		
		query.append("SELECT u ");
		query.append("FROM Usuario u ");
		query.append("	INNER JOIN FETCH u.perfilUsuario p ");
		query.append("WHERE 1 = 1 ");
		
		if(usuario != null && usuario.getNome() != null && !usuario.getNome().trim().equals("")){
			query.append("AND UPPER(u.nome) like :nome ");
			parametros.put("nome", "%"+usuario.getNome().toUpperCase()+"%");
		}
		if(usuario != null && usuario.getEmail() != null && !usuario.getEmail().trim().equals("")){
			query.append("AND UPPER(u.email) like :email ");
			parametros.put("email", "%"+usuario.getEmail().toUpperCase()+"%");
		}
		if(usuario != null && usuario.getLogin() != null && !usuario.getLogin().trim().equals("")){
			query.append("AND UPPER(u.login) like :login ");
			parametros.put("login", "%"+usuario.getLogin().toUpperCase()+"%");
		}
		query.append("ORDER BY u.nome ");
		
		return pesquisarEntidades(query.toString(), parametros);
	}
	
	public Usuario pesquisarUsuarioPorLogin(String login){
		HashMap<String, Object> parametro = new HashMap<String, Object>();
		StringBuilder query = new StringBuilder();
		
		query.append("SELECT u FROM Usuario u WHERE u.login = :login ");
		parametro.put("login", login);
		
		return pesquisarEntidade(query.toString(), parametro);
	}
}

t+

[quote=alissonvla]vc vai ter um DAO, por entidade que vc que vc necessite persistir.
vc vai ter um Facade, por entidade, como se diz “Forte”, no seu sistema.
vc vai ter um Controller, por caso de uso.

dessa forma fica bem divido e facil de se trabalhar.

segue uma classe dao que utiliza a classe basedao que eu te passei.

como vc vai ta usando Jee 6 vc pode fazer tudo no projeto web, ficou facilitou, nao necessita ter varios projetos.

package br.com.bingo.dao;

import java.util.HashMap;
import java.util.List;

import br.com.bingo.entity.Usuario;

public class UsuarioDAO extends BaseDAO<Usuario> {
	
	protected UsuarioDAO() {
		
	}
	
	public List<Usuario> pesquisarUsuarios(Usuario usuario){
		HashMap<String, Object> parametros = new HashMap<String, Object>();
		StringBuilder query = new StringBuilder();
		
		query.append("SELECT u ");
		query.append("FROM Usuario u ");
		query.append("	INNER JOIN FETCH u.perfilUsuario p ");
		query.append("WHERE 1 = 1 ");
		
		if(usuario != null && usuario.getNome() != null && !usuario.getNome().trim().equals("")){
			query.append("AND UPPER(u.nome) like :nome ");
			parametros.put("nome", "%"+usuario.getNome().toUpperCase()+"%");
		}
		if(usuario != null && usuario.getEmail() != null && !usuario.getEmail().trim().equals("")){
			query.append("AND UPPER(u.email) like :email ");
			parametros.put("email", "%"+usuario.getEmail().toUpperCase()+"%");
		}
		if(usuario != null && usuario.getLogin() != null && !usuario.getLogin().trim().equals("")){
			query.append("AND UPPER(u.login) like :login ");
			parametros.put("login", "%"+usuario.getLogin().toUpperCase()+"%");
		}
		query.append("ORDER BY u.nome ");
		
		return pesquisarEntidades(query.toString(), parametros);
	}
	
	public Usuario pesquisarUsuarioPorLogin(String login){
		HashMap<String, Object> parametro = new HashMap<String, Object>();
		StringBuilder query = new StringBuilder();
		
		query.append("SELECT u FROM Usuario u WHERE u.login = :login ");
		parametro.put("login", login);
		
		return pesquisarEntidade(query.toString(), parametro);
	}
}

t+[/quote]

Por gentileza, velhinho, voce poderia postar um exemplo do Facade?

Obrigado!
[]'s

cara,

vou te passar um exemplo do meu sistema, so que eu CDI, entao meu facade é controller tbm.

package br.com.bingo.facede;

import java.util.ArrayList;
import java.util.List;

import javax.ejb.Stateless;
import javax.faces.application.FacesMessage;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;
import javax.inject.Inject;
import javax.inject.Named;

import br.com.bingo.dao.PerfilUsuarioDAO;
import br.com.bingo.dao.UsuarioDAO;
import br.com.bingo.entity.PerfilUsuario;
import br.com.bingo.entity.Usuario;
import br.com.bingo.util.enumerator.TelaEnum;

@Stateless
@Named("UsuarioFacade")
@SessionScoped
public class UsuarioFacade {
	
	@Inject
	private UsuarioDAO usuarioDao;
	
	@Inject
	private PerfilUsuarioDAO perfilUsuarioDao;
	
	@Inject
	private Usuario usuario;
	
	private List<Usuario> listaUsuarios;
	
	public UsuarioFacade(){
		usuario = new Usuario();
	}
	
	public String iniciarConsulta(){
		usuario = new Usuario();
		listaUsuarios = new ArrayList<Usuario>();
		
		return TelaEnum.USUARIO_CONSULTA.getTela();
	}
	
	public String iniciarCadastro(){
		usuario = new Usuario();
		
		return TelaEnum.USUARIO_CADASTRO.getTela();
	}
	
	public void salvar(){
		if(!usuario.getSenha().equals(usuario.getSenhaConfirmacao())){
			FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Senhas não conferem.", null));
		}else if(usuario.getIdUsuario() == null && usuarioDao.pesquisarUsuarioPorLogin(usuario.getLogin()) != null){
			FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Login existente.", null));
		}else{
			try {
				usuario.setPerfilUsuario(perfilUsuarioDao.pesquisar(PerfilUsuario.class, usuario.getPerfilUsuario().getIdPerfilUsuario()));
				
				if(usuario.getIdUsuario() == null){
					usuarioDao.inserir(usuario);
				}else{
					usuarioDao.alterar(usuario);
				}
				usuario = new Usuario();
				
				FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO,"Usuário salvo com sucesso.", null));
			} catch (Exception e) {
				e.printStackTrace();
				FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR,"Ocorreu um erro no sistema.", null));
			}
		}
	}
	
	public void pesquisarUsuarios(){
		listaUsuarios = usuarioDao.pesquisarUsuarios(usuario);
	}
	
	public String voltarConsulta(){
		usuario = new Usuario();
		
		return TelaEnum.USUARIO_CONSULTA.getTela();
	}
	
	public List<Usuario> getListaUsuarios() {
		return listaUsuarios;
	}

	public void setListaUsuarios(List<Usuario> listaUsuarios) {
		this.listaUsuarios = listaUsuarios;
	}
	
	public List<PerfilUsuario> getListaPerfisUsuarios() {
		return perfilUsuarioDao.pesquisarTodosPerfis();
	}

	public Usuario getUsuario() {
		return usuario;
	}

	public void setUsuario(Usuario usuario) {
		this.usuario = usuario;
	}
	
	public String editarUsuario() {
		usuario.setSenhaConfirmacao(usuario.getSenha());
	   
	    return TelaEnum.USUARIO_CADASTRO.getTela();  
	} 
}

[quote=getAdicted][quote=maior_abandonado]uma coisa que eu faço é deixar as entidades e o arquivo de configuração do jpa (persistence.xml) em um outro projeto a parte… os outros referenciando este.

Para os cruds enxergarem as entidades do jpa você fez como? deixou seus projetos de ejb referenciando o de web ?[/quote]

Oi amigo,

Eu deixei as entidades e o persistence.xml do JPA no meu projeto web. Nos cruds, que estão nos módulos, eu utilizei generics :(. O que ce acha?

Valeu a força!
[]'s

Um dos módulos:

[code]package br.com.sisgappe.sessionbeans.impl;

import br.com.sisgappe.sessionbeans.IAgricultura;

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

import javax.ejb.Local;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import javax.persistence.criteria.CriteriaQuery;

@SuppressWarnings(“rawtypes”)
@Stateless
@Local({ IAgricultura.class })
public class AgriculturaBeanImpl<T, ID extends Serializable> implements
IAgricultura {

@PersistenceContext
private EntityManager entityManager;

public EntityManager getEntityManager() {
	return entityManager;
}

public void setEntityManager(EntityManager entityManager) {
	this.entityManager = entityManager;
}

@SuppressWarnings("unchecked")
@Override
public List&lt;T&gt; listAll(Object entity) {
	Query query = this.getEntityManager().createQuery(
			"from " + entity.getClass().getName());
	return query.getResultList();
}

@Override
public void save(Object entity) {
	this.getEntityManager().persist(entity);
}

@Override
public List&lt;T&gt; findByCriteria(CriteriaQuery... criterion) {
	// TODO Auto-generated method stub
	return null;
}

@SuppressWarnings("unchecked")
@Override
public List&lt;T&gt; findBySQL(String sql) {
	Query query = this.getEntityManager().createNativeQuery(sql);
	return query.getResultList();
}

@Override
public void update(Object entity) {
	this.getEntityManager().merge(entity);
}

@Override
public Object findById(Object entity, Serializable id) {
	return this.getEntityManager().getReference(entity.getClass(), id);

}

@Override
public void delete(Object entity, Serializable id) {
	this.findById(entity, id);

}

}
[/code]

[/quote]

eu me arrisco a dizer que isso é uma questão um pouco polemica, vai bastante da opinião da pessoa, vai também dos requisitos encontrados… tem aquela questão dos repositórios e daos, há os que dizem (muitas vezes papagaios de piratas, as vezes alguns argumentos fundamentados aparecem) simplesmente “não use EJB”… enfim.

a minha opinião, pelo que tenho de experiência, é que é bom um dao genérico, mas normalmente você também vai precisar de daos específicos (que eu costumo fazer herdando o genérico)… vi l que você criou um findBySql (dei uma olhada bem básica, só um pouco nas assinaturas dos métodos), isso deixa de certa forma deixa mais abstrato você criaria sua sql em outro lugar e passa para o dao, mas eu tenho a opinião de que os comandos sql também deveriam ser criados em daos (normalmente isso cai nos específicos que falei), e o modelo simplesmente chamaria esse dao, classes de negocio do modelo não deveriam criar comandos sql na minha opinião.

Outra coisa também, nada impede de você deixar os daos em session beans, é funcional, mas o comumente usado é você deixar toda sua camada de modelo no session bean e injetar o dao no modelo, o dao poderia ser um session bean também injetado no modelo que é outro session bean, esse sim chamado no controle, ou melhor ainda, você pode construir fachadas destes modelos para serem chamadas pelos controles (da uma pesquisadinha em [google]façade session bean[/google]).

A forma que eu faço é deixar os seus beans do jpa em um projeto a parte por que os uso tanto no modelo como nas telas da view por exemplo, se tiver tabelas na view que costumam ser list<algum objeto, normalmente estes beans> para usa-los em todos os projetos, tanto nos ejbs quanto na aplicação web/desktop que acessar o ejb.

bom… eu não estou dizendo que essa é a forma correta de se fazer, mas é a forma que eu faço, amanhã posso aprender com outra pessoa (ou até sozinho quem sabe) outra forma melhor.

Olá!

A meu ver existem alguns problemas na divisão de responsabilidades. O projeto Web está fazendo muito mais coisas do que deveria, como: armazenar entidades, implementar as regras de negócio, e até mesmo montar queries SQL.

Analise cuidadosamente as sugestões apresentadas ao longo do tópico, elas vão melhorar bastante a arquitetura de seu projeto.

E procure observar os seguintes princípios:

  • Os DAOs são os únicos responsáveis pela persistência. Nenhum outro componente deve ter conhecimento da estrutura do banco de dados ou das consultas envolvidas.
  • Classes de negócio devem fornecer operações completas, quer dizer, a View não deve executar as regras de negócio e chamar os EJBs apenas para persistência.
  • A view é apenas a apresentação. Sua responsabilidade se restringe a fazer interface com o usuário, receber seus inputs, validar e acionar outras classes para execução das operações de negócio.

Obrigado pelas opiniões amigos!

Só um parenteses aqui, e desculpem a enxurrada de perguntas. A minha ideia eh criar três projetos EJBs e um projeto Web, utilizando o mesmo EAR, eu pensei em fazer isso para tentar aumentar a coesão e permitir maior escalabilidade com menos esforços.

Na opinião de voces, eh melhor fazer o que eu mencionei, ou criar apenas um projeto Web?

Obrigado a todos pela paciência!

[]'s

[quote=maior_abandonado][quote=getAdicted][quote=maior_abandonado]uma coisa que eu faço é deixar as entidades e o arquivo de configuração do jpa (persistence.xml) em um outro projeto a parte… os outros referenciando este.

Para os cruds enxergarem as entidades do jpa você fez como? deixou seus projetos de ejb referenciando o de web ?[/quote]

Oi amigo,

Eu deixei as entidades e o persistence.xml do JPA no meu projeto web. Nos cruds, que estão nos módulos, eu utilizei generics :(. O que ce acha?

Valeu a força!
[]'s

Um dos módulos:

[code]package br.com.sisgappe.sessionbeans.impl;

import br.com.sisgappe.sessionbeans.IAgricultura;

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

import javax.ejb.Local;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import javax.persistence.criteria.CriteriaQuery;

@SuppressWarnings(“rawtypes”)
@Stateless
@Local({ IAgricultura.class })
public class AgriculturaBeanImpl<T, ID extends Serializable> implements
IAgricultura {

@PersistenceContext
private EntityManager entityManager;

public EntityManager getEntityManager() {
	return entityManager;
}

public void setEntityManager(EntityManager entityManager) {
	this.entityManager = entityManager;
}

@SuppressWarnings("unchecked")
@Override
public List&lt;T&gt; listAll(Object entity) {
	Query query = this.getEntityManager().createQuery(
			"from " + entity.getClass().getName());
	return query.getResultList();
}

@Override
public void save(Object entity) {
	this.getEntityManager().persist(entity);
}

@Override
public List&lt;T&gt; findByCriteria(CriteriaQuery... criterion) {
	// TODO Auto-generated method stub
	return null;
}

@SuppressWarnings("unchecked")
@Override
public List&lt;T&gt; findBySQL(String sql) {
	Query query = this.getEntityManager().createNativeQuery(sql);
	return query.getResultList();
}

@Override
public void update(Object entity) {
	this.getEntityManager().merge(entity);
}

@Override
public Object findById(Object entity, Serializable id) {
	return this.getEntityManager().getReference(entity.getClass(), id);

}

@Override
public void delete(Object entity, Serializable id) {
	this.findById(entity, id);

}

}
[/code]

[/quote]

A forma que eu faço é deixar os seus beans do jpa em um projeto a parte por que os uso tanto no modelo como nas telas da view por exemplo, se tiver tabelas na view que costumam ser list<algum objeto, normalmente estes beans> para usa-los em todos os projetos, tanto nos ejbs quanto na aplicação web/desktop que acessar o ejb.
[/quote]

Bem interessante esse método, já foi incorporado ao meu projeto. Obrigado maior_abandonado. Valeu gomesrod e alissonvla tambem!

Já estou quase fechando o escopo em termos de tecnologia, só resta a questão do meu post anterior a esse. Vou continuar pesquisando, qualquer novidade, eu posto.

Valeu rapaziada. Sucesso! :smiley:

[]'s