Problemas com JPA + LAZY + EJB

14 respostas
rodolfoliviero

Tenho o seguinte codigo:

@Stateless
public class TesteDAOImpl implements TesteDAO {
	
	@PersistenceContext(unitName="manager")
	private EntityManager em;

	public Produto getProduto(Integer id) {
		Produto produto = em.getReference(Produto.class, id);
		return produto;
	}

Se lá no meu cliente pego o produto atravez dessa DAO ai vou pegar as categorias ou ate o nome do produto que nem relacionamento possui ocorre a tao famosa LazyInitializationException alguem tem alguma ideia de como resolvo isso(não quero mapear como FetchType.EAGER) e nem colocor no codigo algo como produto.getCategorias().size…
Ah estou usando jpa + hibernate.
Att…

14 Respostas

T

Do JPA só uso annotations, mas se for igual ao hibernate, tu precisa de uma sessão aberta pra carregar uma coleção lazy.

rodolfoliviero

Então exato…eu preciso da sessão aberta, so que quem contralola isso eh o conteiner de aplicação no meu casso o jboss e por algum motivo ele fecha a sessão logo apos ele pegar o obj

T

Nunca mexi com controle de sessão por container. Mas dá uma procura no google, tu deve ter que declarar a classe toda como transacional

rodolfoliviero

dei uma procurada na net mais ainda nao achei nada concreto…mas vou dar uma olhada nessa questao do transacional

urubatan

se este é um statefull session bean
tenta utilizar um ExtendedPersistenceContext que deve resolver o problema …

rodolfoliviero

Valeu urubatan
Resolvido…ficou assim

com um session bean statefull eh so usar a anotacao assim @PersistenceContext(type=PersistenceContextType.EXTENDED)
EntityManager em;

e com um session bean stateless eh so usar uma anotacao assim
@PersistenceContext(type=PersistenceContextType.TRANSACTION)

porem nos dois casos tive q trocar a minha implementacao do getProduto por
em.find pois com com em.getReference nao funcionou em nenhum dos casos…Se Alguem souber pq posta ai
faloww

Fabio_Kung

Não tem jeito, é isso mesmo.

Pior ainda se o cliente do seu ejb for remoto. Aí nem o PersistenceContextType.EXTENDED resolve.

Precisa iniciar a coleção de alguma forma (ou mapear como EAGER), pois o objeto que é serializado e enviado ao cliente é detached.

rodolfoliviero

valew kung pela dica…
Não acredito…eu ia usar varios clientes remotos…eh vou mudar pra eager

D

Opa…

Estou passando pelo mesmo problema…

no meu caso, estou fazendo assim:

:arrow: Chamada LOCAL em um STATELESS
:arrow: Meu EntityManager está anotado com @PersistenceContext(type=PersistenceContextType.TRANSACTION)

como mesmo assim continuei tomando LazyInitializationException, fiz o seguinte:
:arrow: No meu ServletFilter, no doFilter(), abri um UserTransaction antes e comitei depois

mesmo assim não teve jeito… LazyInitializationException persiste…

no meu persistence.xml meu persistence-unit está com transaction-type=“JTA”
pego a conexao assim: java:MyDS

alguem sabe como resolver?

Deve ter alguma forma de usar Lazy Loading em chamadas locais para um stateless session bean.

valeu!

D

resolvi mudando meu SessionBeans para Stateful…
mas nao queria que fossem stateful…

alguém sabe se é possivel usar lazy loading com stateless

lembrando que estou fazendo apenas chamadas locais

valeu

D

sabia que ia dar merda com Stateful…
parece que a session do hibernate ficou aberta… e aí tomei um “Illegal attempt to associate a collection with two open sessions”

deve ser porque preciso destruir o Stateful… mas aí vou ter que editar toooodo o projeto para chamar algum metodo que destroi o Stateful em questao…

perfeito mesmo seria com Stateless mas não consigo fazer o Lazy Loading funcionar com ele

se alguem souber a solução, agradeço.

valeu!

guigouz

Fabio Kung:
Não tem jeito, é isso mesmo.

Pior ainda se o cliente do seu ejb for remoto. Aí nem o PersistenceContextType.EXTENDED resolve.

Precisa iniciar a coleção de alguma forma (ou mapear como EAGER), pois o objeto que é serializado e enviado ao cliente é detached.

Se você tem muitas coleções, não dá pra mapear tudo como eager… ele reclama de umas bags, sei lá.

To vendo os mesmos problemas de vocês, e como neste post, ainda não achei uma maneira eficiente de contornar (no momento to pegando uma lista de entidades, e quando vou ler uma entidade, faço outra query usando Hibernate.initialize com os campos)

guigouz

E mesmo assim não tá funcionando.

L

Eu coloquei esse método no EJB e agora quando preciso carregar o relacionamento eu o uso.

public Collection loadLazyRelationship(Object myEntity, String relacionamento) {
    String ejbql = 
        "select o." + relacionamento + " from " + myEntity.getClass().getSimpleName() + 
        " o LEFT JOIN FETCH o." + relacionamento + " where o = :myEntity";

    Query query = em.createQuery(ejbql);
    query.setParameter("myEntity", myEntity);

    Collection l = query.getResultList();

    return l;
}
Criado 12 de dezembro de 2006
Ultima resposta 17 de nov. de 2008
Respostas 14
Participantes 7