OpenSessionInViewFilter + Flex + Spring + Hibernate

3 respostas
R

Fala pessoal blz?

Seguinte, estou com um problema que ta me tirando o sono… Estou em um projeto de uma aplicação que envolve JAVA de backend e Flex de FrontEnd. Utilizo o BlazeDS com Spring. Tive problemas do famoso LazyLoad, ai implementei o padrão OpensessionInViewFilter, e tudo funcionou a mil maravilhas. Quando precisava de uma entidade usava um JOIN FETCH direto nas minhas queries , e ele trazia para a interface os objetos necessários. Só que executando diversos testes verifiquei um problema que aparentemente já revirei a internet e não consigo resolver.

Vou generalizar, caso não dê pra entender colocarei meu código:

1 -> Tenho uma entidade A com diversos relacionamentos LAZY=TRUE, quando faço o select nessa entidade coloco o “LEFT OUTER JOIN FETCH” para as entidades que desejo que sejam carregadas. ÓTIMO, quando faço uma pesquisa todas essas entidades veêm preenchidas como eu preciso. Quando vou salvar qualquer uma dessas entidades, o ENTITY MANAGER não realiza o refresh antes da função executar o retorno. Então o que acontece, ele serializa o objeto para o flex sem inicializar as variáveis LAZY, e elas chegam la nulas. É possível ver no console do do TOMCAT o hibernate executando as queries dos joins após o retorno da função, só que já é tarde demais, pois o objeto já foi serializado para o flex. Algumas vezes esses selects do hibernate acontecem antes do retorno e o objeto é transferido certo.

2-> Esse problema só ocorre na hora de salvar o objeto, ou quando eu tenho mais de uma operação sendo chamada no entitymanager por exemplo:

  • em.find(objeto1)
  • em.find(objeto2)
  • em.find(objeto3)

E assim por diante, ele coloca todas operações na fila e executa as mesmas, mas o carregamento dos relacionamentos load é feito asíncrono, ele marca as variávies com aquele $$_javassist e retorna para o Flex.

Alguém sabe como forçar que esse Fetch seja feito antes do retorno da função?

Desde já agradeço

3 Respostas

Paulo_Silveira

Ola Rafael

Voce pode fazer de varias formas: utilizar o Hibernate.initialize(objeto.getRelacionamento()), ou fazer um JOIN FETCH atraves do HQL ou usar algum framework que te auxilie a isso para o Flex, como o BlazeDS.

Aqui tem um pouco mais:

abracos

R

Já uso o blaze DS e estou fazendo o join fetch… o problema é q o join fetch esta indo de maneira asíncrona

paulo.ps84

RafaelPossas, conseguiu resolver esse problema? Estou com um problema parecido também para realizar essa integração com o BlazeDS, coloquei o OpenSessionInView para rodar, resolveu o problema "Lazy" mas parece que o Spring não esta efetuando o controle das transações direito, deve ser algum erro de conf., estou conseguindo salvar, deletar, listar... mas as vezes no update, tenho retorno de que o registro esta sendo usado em outra transação.
Exemplo: Carrego um Usuario para o Flex, altero uma propriedade e mando salvar.... blz ele salva, logo em seguida altero de novo esta propriedade e mando salvar novamente, nesse momento ele gera o erro.....

Estou usando também os "join fetch" para trazer o necessário....

Estou falando a respeito do controle de transação, porque quando retirei a anotação @Transaction do método e depois retirei o OpenSessionInView ele começou a lançar exceções dizendo q não existia nenhuma transação, e com o OpenSessionInView ativo funciona mesmo sem a anotação @Transaction.

segue as conf:

web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
  <display-name>ibs-server</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>

  <!-- Configuração do Log4j -->
  
  <context-param>
  	<param-name>log4jConfigLocation</param-name> 
  	<param-value>/WEB-INF/log4j.properties</param-value> 
  </context-param>
  
  <listener>
	<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
  </listener>
  
  <!-- Configuração MessageBroker para o Spring-->
  
  <context-param>
  	<param-name>contextConfigLocation</param-name> 
  	<param-value>/WEB-INF/applicationContext.xml</param-value> 
  </context-param>
 
  <listener>
  	<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
  
  <listener>
  	<listener-class>flex.messaging.HttpFlexSession</listener-class>
  </listener>
  
  <servlet>
  	<servlet-name>flex</servlet-name>
  	<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>
  
  <servlet-mapping>
  	<servlet-name>flex</servlet-name>
  	<url-pattern>/messagebroker/*</url-pattern>
  </servlet-mapping>
  
  <!-- Configuração para o OpenSessionInView -->
  <filter>  
	<filter-name>openSessionInViewFilter</filter-name>  
    <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>  
  </filter>  
 
  <filter-mapping>  
	<filter-name>openSessionInViewFilter</filter-name>  
	<url-pattern>/*</url-pattern>  
  </filter-mapping>  
	
</web-app>
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans 
	xmlns="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:jdbc="http://www.springframework.org/schema/jdbc"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    
    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/jdbc
        http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd
        ">
            
    <context:component-scan base-package="br.com.ibs"/>        
    
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
	    <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
	    <property name="url" value="jdbc:mysql://localhost:3306/ibs"/>
	    <property name="username" value="root"/>
	    <property name="password" value="123"/>
	</bean>
    
    <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
    	<property name="dataSource" ref="dataSource"/>
    	<property name="packagesToScan" value="br.com.ibs.*.model"/>
    	<property name="hibernateProperties">
    		<props>
    			<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</prop>
    			<prop key="hibernate.hbm2ddl.auto">update</prop>
    			<prop key="hibernate.show_sql">true</prop>
				<prop key="hibernate.format_sql">true</prop>
				<prop key="log4j.logger.net.sf.hibernate">debug</prop>
			</props>
    	</property>
    </bean>
    
    <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    	<property name="sessionFactory" ref="sessionFactory"/>
    </bean>
       
    <tx:annotation-driven transaction-manager="transactionManager"/>
</beans>
flex-servlet.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:flex="http://www.springframework.org/schema/flex"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="
		http://www.springframework.org/schema/beans
		http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
		http://www.springframework.org/schema/flex 
		http://www.springframework.org/schema/flex/spring-flex-1.0.xsd">

	<bean id="flexException" class="br.com.ibs.util.FlexException"/>
	
	<flex:message-broker>		
		<flex:exception-translator ref="flexException"/>
		<flex:message-service default-channels="my-amf"/>					
	</flex:message-broker>

</beans>
Criado 20 de junho de 2010
Ultima resposta 15 de abr. de 2011
Respostas 3
Participantes 3