LazyException JPA + Hibernate + Spring, socorro amigos!

7 respostas
alias

Amigos do forum, por favor, me ajudem,

Não estou conseguindo resolver esse problema de Lazy nem com reza brava. Imagino que seja algum problema nos meus arquivos de config…mas nao sei o que é, se possivel me ajudem amigos, por favor!

persistence-xml:

<persistence-unit name="">
		<provider>org.hibernate.ejb.HibernatePersistence</provider>
		

		<properties>
			
			<property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver"/>
			<property name="hibernate.connection.url" value="jdbc:mysql://localhost/easymotors2"/>
			<property name="hibernate.connection.username" value="easy"/>
			<property name="hibernate.connection.password" value="motors"/>
			<property name="hibernate.dialect" value="br.com.easymotors.site.hibernate.CustomMySQLDialect" />
			<property name="hibernate.show_sql" value="true"/>
			<property name="hibernate.format_sql" value="false"/>
			<property name="hibernate.connection.autocommit" value="false" />
			
			<!-- 
			<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
			<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost/easymotors2"/>
			<property name="javax.persistence.jdbc.user" value="easy"/>
			<property name="javax.persistence.jdbc.password" value="motors"/>
			 -->
			
			<property name="hibernate.connection.provider_class" value="org.hibernate.connection.C3P0ConnectionProvider" />
			<property name="hibernate.c3p0.min_size" value="5" />
			<property name="hibernate.c3p0.max_size" value="20" />
			<property name="hibernate.c3p0.timeout" value="180" />
			<property name="hibernate.c3p0.idle_test_period" value="100" />
			 
			<property name="hibernate.cache.use_second_level_cache" value="true"/>
			<property name="hibernate.cache.provider_class" value="org.hibernate.cache.EhCacheProvider"/>
			<property name="hibernate.cache.use_query_cache" value="true"/>
		</properties>	
	</persistence-unit>

arquivo do spring:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
	xmlns:tx="http://www.springframework.org/schema/tx"
	xsi:schemaLocation="
		http://www.springframework.org/schema/beans	http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
	    http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
	    http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">

	<context:component-scan base-package="br.com.easymotors.site" />
	
	<tx:annotation-driven transaction-manager="myTransactionManager" proxy-target-class="true"/>
	
	<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
		<property name="persistenceUnitName" value="easymotors" />
	</bean>
	
	<bean id="myTransactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
		<property name="entityManagerFactory" ref="entityManagerFactory" />
	</bean>
	
	<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
	<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />
	
	
</beans>

Eis o erro, um clássico:

org.hibernate.LazyInitializationException: could not initialize proxy - no Session

E no meu web.xml está o filtro para a implementacao do Spring do OpenEntityManagerInView

O que poderia ser amigos, que está errado?

Obrigado!

7 Respostas

nextuser

vc deve colocar @Transaction nas classes ou metodos que vai trabalhar com o objeto que tem o lazy… pq quando vc acessar a lista ele vai buscar no banco mas só terá session se estiver anotado…

alias

Valeu, amigão, brigado mesmo, mas nao entendi direito…o @Transaction precisa estar na minha classe DAO que vai buscar a entidade?

O cenário é assim: faço um select e preencho uma grid, é selecionado um registro dessa listagem e o mesmo vai para a sessão (é a regra de negócio do produto)

Na pagina seguinte, tenho um método que lê essa entidade que anteriormente, como disse, foi salva na sessão HTTP. Estou sem o codigo agora mas é assim:

entidade.getEntidadeAnotadaComLazy().getAtributo; //o erro ocorre na tentativa do Hibernate em acessar esse ultimo atributo.

Não entendi onde teria que incluir o @Transactional

O triste é que eu havia feito manualmente o OpenSessionInViewFilter, e usando apenas Hibernate (sem as interfaces do JPA nem Spring) na aplicação, e estava tudo funcionando… quisemos melhorar o código para usar as interfaces do JPA e o Spring e ferrou tudo :lol:

Valeu amigos, obrigado!

nextuser

no metodo ou classe que vc está fazendo entidade.getEntidadeAnotadaComLazy().getAtributo; deve ter o @Transaction

alias

Mas é uma classe de negócio, ela nao acessa o banco! Procede incluir o @Transaction nesse cara?

Valeu amigo!

nextuser

mas quando ela está fazendo entidade.getEntidadeAnotadaComLazy() ela acessa o banco… por isso que está dando o erro que não tem session… se ela for anotada e suas configs estiverem certas vai funcionar

alias

O problema,entao, é que como a chamada não está em um contexto transacional, o Hibernate não consegue achar/criar a Session?Seria isso ou entendi errado?

Se sim, o OpenEntityManagerInViewFilter não serve justamente para resolver esse fato?

Com relação ao @Transaction, provavelmente estou fazendo besteira com relação a isso. Vejam amigos, a estrutura está assim:

Interface Dao genérica com métodos consultar, alterar, incluir, etc,
.
.-> essa interface é implementada em uma classe abstrata JpaDao que usa o EntityManager ->
.
.-> aqui vem um classe abstrata HibernateDao, que herda JpaDao, que tem alguns outros metodos pra casos de “necessidades alternativas” com a Session :lol:
.
.-> aqui vem o MinhaRegraDeNegocioDao (ufa), que herda HibernateDao

A anotação @Transaction deve ir na classe concreta (XptoDao), ou na interface?

Valeu amigos!

alias

Olá amigos do fórum,

passando para registrar a “solução” do problema, caso outros tenham o mesmo problema (ao menos a solução encontrada, se é a correta sabe Deus :lol:)

O que o colega nextuser comentou a respeito da transação tinha fundamento…pois não comentei algo a respeito do meu fluxo, que se trata de uma CONVERSAÇÃO. Seria realmente necessario manter o EntityManager em um escopo transacional/“conversacional” para que ele se mantesse aberto. E pelo que entendi da questão (me corrijam por favor se estiver errado), o OpenEntityManagerInView não resolve essa situação, pois mantem a sessão aberta durante o processo de renderização.

O mesmo problema ocorreu em paginas onde ocorria uma “pseudo-conversação” com o uso de Ajax (faço o select, o OpenEntityManagerInView mantem a sessão aberta durante o processo, e em algum “reRender” da vida eu lia algum cara LAZY -> ocorria o erro)

Minha “solução” foi incluir o Seam no projeto e usar o escopo de conversação para esses casos. Isso me levará a outro tópico fatalmente :lol:

Valeu nextuser, e a todos.

Criado 19 de maio de 2011
Ultima resposta 26 de mai. de 2011
Respostas 7
Participantes 2