LazyInitializationException 2 dias tentando resolver :( [Resolvido]

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

[code]@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;

}[/code]

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

[code]<?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"/>

[/code]

grato…

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

Quem sabe ajuda

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

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;

:wink:

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

grato…

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.

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… :frowning:

[code]

<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>[/code]

Troque a ordem.

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

[quote=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.
[/quote]

Onde você viu isso?

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

[quote=Leozin][quote=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.
[/quote]

Onde você viu isso?

EDIT: quando tentei usar o OpenSessionInView não tinha funcionado :([/quote]

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.

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

grato…

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

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?