LazyInitializationException 2 dias tentando resolver :( [Resolvido]

12 respostas
R

diante dos códigos a seguir, em que vocês vocês acham que estou vacilando?

@Entity
public class ServiceOrder {

	@ManyToOne(fetch = FetchType.LAZY)
	@JoinColumn (name="customer_id")
	@Cascade (CascadeType.ALL)
    private Customer customer;

    @OneToMany(mappedBy = "serviceOrder", fetch = FetchType.LAZY)
    @JoinColumn(name="serviceorder_id")
    @Cascade(CascadeType.ALL) 
    private List<ServiceOrderDevice> devices;

...

}

Método da action ServiceOrderAction que da o erro failed to lazily initialize a collection of role: jpa.ServiceOrder.devices, no session or session was closed

public String print() {
		serviceOrder = serviceOrderDAO.find(serviceOrderID);
		return "print";
	}

applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
...

	<!-- Spring Annotation -->
	<sa:annotation-autoload />
	
	<!-- AspectJ -->
	<aop:aspectj-autoproxy proxy-target-class="false" />
	

	<!-- JPA -->
	<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />


	<!-- Gerenciador de Persistencia de Entitys -->	
	<bean id="entityManagerFactory"	class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
		<property name="dataSource" ref="dataSource" />
		<property name="jpaVendorAdapter">
			<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
				<property name="database" value="MYSQL" />
				<property name="showSql" value="true" />
			</bean>
		</property>
	</bean>

	<!-- DataSource -->
	<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
		<property name="driverClassName" value="com.mysql.jdbc.Driver" />
		<property name="url" value="jdbc:mysql://###.###.###.##:3306/os" />
		<property name="username" value="root" />
		<property name="password" value="root" />
	</bean>

	<!-- Controlador de Transação -->
	<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
		<property name="entityManagerFactory" ref="entityManagerFactory" />
	</bean>

	<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="false"/>
	
</beans>

grato...

12 Respostas

dudaskank

veja se este é o mesmo problema que teve nesse tópico: http://www.guj.com.br/posts/list/25262.java

Quem sabe ajuda

R

eu não to usando a classe HibernateUtil, é necessário?

Leozin

o problema é que a sessão está fechada

Existem duas maneiras de resolver isso:

1- Toda vez que tu fazer um Lazy Loading, você precisa estar dentro de uma transação.
2- Fazer o teu persistence context ser “extended”

@PersistenceContext(type=PersistenceContextType.EXTENDED) private EntityManager em;

R

:wink:

testei o @PersistenceContext(type=PersistenceContextType.EXTENDED) e está tudo ok agora!!

grato…

L

Não use PersistenceContextType.EXTENDED fora de um Stateful Session Bean do EJB!!!

A idéia do extended é o gerenciador do EJB fechar o contexto automaticamente. Mas fora do EJB, ninguém fechará, nem o Spring fará isso.

Ao invés de extended, utilize o filtro OpenEntityManagerInViewFilter, que vem junto com o Spring.

R

retirei o EXTENDED e acrescentei no web.xml o código abaixo que está com o comentário OpenEntityManagerInViewFilter, daí o erro voltou failed to lazily initialize a collection of role: jpa.ServiceOrder.devices, no session or session was closed.... :(

<!--  Struts 2.0 Filter -->

	<filter>

		<filter-name>struts2</filter-name>
		<filter-class>
			org.apache.struts2.dispatcher.FilterDispatcher
		</filter-class>

		<init-param>
			<param-name>actionPackages</param-name>
			<param-value>struts2</param-value>
		</init-param>

	</filter>

	<filter-mapping>
		<filter-name>struts2</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>
	
         <!-- OpenEntityManagerInViewFilter-->
     <filter>
		<filter-name>openEntityManagerInViewFilter</filter-name>
		<filter-class>org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter</filter-class>
	</filter>
	
	<filter-mapping>
		<filter-name>openEntityManagerInViewFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>
         <!-- *********************** -->


	<!-- Spring 2.0 -->

	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>classpath:/applicationContext*.xml</param-value>
	</context-param>

	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>

	<listener>
		<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
	</listener>
L

Troque a ordem.

Primeiro de todos é o openEntityManagerInViewFilter, depois o Filter do Struts.

Leozin

Leonardo3001:
Não use PersistenceContextType.EXTENDED fora de um Stateful Session Bean do EJB!!!

A idéia do extended é o gerenciador do EJB fechar o contexto automaticamente. Mas fora do EJB, ninguém fechará, nem o Spring fará isso.

Onde você viu isso?

EDIT: quando tentei usar o OpenSessionInView não tinha funcionado :frowning:

L

Leozin:
Leonardo3001:
Não use PersistenceContextType.EXTENDED fora de um Stateful Session Bean do EJB!!!

A idéia do extended é o gerenciador do EJB fechar o contexto automaticamente. Mas fora do EJB, ninguém fechará, nem o Spring fará isso.

Onde você viu isso?

EDIT: quando tentei usar o OpenSessionInView não tinha funcionado :(

Seguinte, eu passei por esse mesmo problema há um mês atrás. E sabia há muito tempo que só se poderia usar EXTENDED em Stateful Session Bean, não em Stateless Session Bean. Pois bem, mas e fora do EJB, como o Spring? Dei uma bela googlada e encontrei esses comentários no fórum do Spring: http://forum.springframework.org/archive/index.php/t-27430.html .

São perguntas que ultrapassam um ano e que não responde à pergunta: “o Spring vai fechar o PersistenceContext quanto se usa extended?”. Outra, porque o Spring possui o Filtro OpenEntityManagerInViewFilter? Será que é porque não há suporte eficaz ao EXTENDED?

Com isso, ligando o excesso de interrogações do fórum mais a existência desse filtro, fiquei na opção “precavido” e assumi que o EXTENDED nunca será fechado e que deve ser evitado.

R

obrigado a todos, troquei a ordem e ficou tudo blz agora!

grato…

Leozin

Um problema que o Spring quando usa o EXTEND é que, como pelo jeito ele não fecha mesmo, quando você insere dados no teu banco de dados enquanto o contexto está aberto, esses dados que foram inseridos “na mão” não são carregados quando você faz por exemplo, um select

G

Voltando o post…

Estou com o mesmo problema de Lazy, mas aqui já estou usando o OpenEntityManagerInViewFilter no meu web.xml e ele está no começo da definição dos filtros.

Alguma sugestão?

Criado 30 de julho de 2008
Ultima resposta 16 de abr. de 2012
Respostas 12
Participantes 5