<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
	<channel>
		<title><![CDATA[Latest posts for the topic "JPA + Tomcat + Mentawai"]]></title>
		<link>http://forum.mentaframework.org/posts/list/3.page</link>
		<description><![CDATA[Latest messages posted in the topic "JPA + Tomcat + Mentawai"]]></description>
		<generator>JForum - http://www.jforum.net</generator>
			<item>
				<title>JPA + Tomcat + Mentawai</title>
				<description><![CDATA[ Estou com alguns problemas com o uso da JPA no Tomcat e talvez vocês possam me ajudar..

Usando a implementação Toplink, criei um projeto com uma tela inicial de Login.

O que está acontecendo é que quando o site é carregado e o formulário de Login submetido, a autenticação falha, ou seja, o usuário informado do formulário não é encontrado. 

Constatei que isso acontece porque o contexo/conexão JPA ainda não está concluída. Isto é, se eu tendo o Login uma vez, duas vezes, na terceira vez ele acontece com sucesso, exatamente no momento em que a conexão JPA está realizada.

Não consigo entender por quê isso acontece, na máquina local não tenho esse problema.

O método de login não deveria aguardar o término da criação do contexto?

Criei um filtro. Quando a action responsável pelo login é invocada, no seu input "vem" um EntityManager com uma transação aberta. Quando a action é encerrada o filtro comita a transação e fecha o EntityManager (close).

Quando a aplicação é inicializada (filtro é instanciado no ApplicationManager - loadActions) acontece a criação do EMF (EntityManagerFactory) do contexto em questão.

O que pode estar errado?


<b>ApplicationManager</b>
<span class="genmed"><b>Code:</b></span><br>
		<div style="overflow: auto; width: 100%;">
		<pre>
	public void loadActions&#40;&#41; {
	
		
        
		
        filter&#40;new JPAFilter&#40;"PU"&#41;&#41;; 

		
		/* Filtro de autenticação */
		addGlobalFilter &#40;new AuthenticationFilter&#40;&#41;&#41;;
		addGlobalConsequence&#40;AuthenticationFilter.LOGIN	, new Redirect&#40;"/index.jsp"&#41;&#41;;
		//Login
		ActionConfig ac = new ActionConfig&#40;"/Login", LoginAction.class&#41;;
		ac.addConsequence&#40;LoginAction.SUCCESS,  new Redirect &#40;"/index.jsp"&#41;&#41;;
		ac.addConsequence&#40;LoginAction.ERROR, new Forward &#40;"/index.jsp"&#41;&#41;;
		addActionConfig&#40;ac&#41;;
		
		ac.addFilter&#40;new RedirectAfterLoginFilter&#40;&#41;&#41;;
		ac.addConsequence&#40;RedirectAfterLoginFilter.REDIR, new Redirect&#40;&#41;&#41;;
		//Logout
		ac = new ActionConfig&#40;"/Logout", LogoutAction.class&#41;;
		ac.addConsequence&#40;LogoutAction.SUCCESS, new Redirect&#40;"/index.jsp"&#41;&#41;;
		addActionConfig&#40;ac&#41;;
		/* Fim do filtro de autenticação */
		

}

</pre>
		</div>


<b>Filtro para o JPA</b>
<span class="genmed"><b>Code:</b></span><br>
		<div style="overflow: auto; width: 100%;">
		<pre>

public class JPAFilter extends InputWrapper implements AfterConsequenceFilter {


	public static final String KEY = "jpa_entityManager";

	private String EntityManagerKEY = KEY;
		
	private EntityManagerFactory emf;
	
	private ThreadLocal&lt;EntityManager&gt; emLocal = new ThreadLocal&lt;EntityManager&gt;&#40;&#41;;
	
	private ThreadLocal&lt;EntityTransaction&gt; transLocal = new ThreadLocal&lt;EntityTransaction&gt;&#40;&#41;;



	/**
	 * Construtor
	 * 
	 * @param persistenceUnit
	 */
	public JPAFilter&#40;String persistenceUnit&#41; {
		Factory.setPU&#40;persistenceUnit&#41;;
		Factory.getInstance&#40;&#41;;
		
	}



	
	public String filter&#40;InvocationChain chain&#41; throws Exception {
		
		Action action = chain.getAction&#40;&#41;;

		super.setInput&#40;action.getInput&#40;&#41;&#41;;

		action.setInput&#40;this&#41;;

		String result = chain.invoke&#40;&#41;;

		
		return result;
	}

	public void afterConsequence&#40;Action action, Consequence c,
			boolean conseqExecuted, boolean actionExecuted, String result&#41; {

		EntityManager em = emLocal.get&#40;&#41;;
 
		if &#40;em != null&#41; {
			try {
				em.getTransaction&#40;&#41;.commit&#40;&#41;;	
			} catch &#40;Exception e&#41; {
				Debug.log&#40;"Não foi possível efetuar COMMIT da na transação.",  "Mensagem: " + e.getMessage&#40;&#41;&#41;;
			}
			
			em.close&#40;&#41;;
			emLocal.set&#40;null&#41;;
			removeValue&#40;EntityManagerKEY&#41;;
		}
	}

	public void destroy&#40;&#41; {
		Factory.close&#40;&#41;;
		
	}

	public Object getValue&#40;String key&#41; {
		
			
		if &#40;key.equals&#40;EntityManagerKEY&#41;&#41; {
		
			
			EntityManager em = emLocal.get&#40;&#41;;
			
			if &#40;em == null&#41; {
				
				try {
					em = Factory.getInstance&#40;&#41;.getEntityManager&#40;&#41;;  
					emLocal.set&#40;em&#41;;
					
				} catch &#40;Exception e&#41; {
					Debug.log&#40;"Não foi possível criar EntityManager.",  "Mensagem: " + e.getMessage&#40;&#41;&#41;;
				}
			}
			
			
			em = emLocal.get&#40;&#41;;
			if &#40;em != null&#41;{
				
				try {
					em.getTransaction&#40;&#41;.begin&#40;&#41;; 
					setValue&#40;key, em&#41;;
				} catch &#40;Exception e&#41; {
					Debug.log&#40;"Não foi possível efetuar start da na transação.",  "Mensagem: " + e.getMessage&#40;&#41;&#41;;		
				}
			} 
			
			

			return em;
			}

		return super.getValue&#40;key&#41;;
	}

</pre>
		</div>


<b>Factory</b>
<span class="genmed"><b>Code:</b></span><br>
		<div style="overflow: auto; width: 100%;">
		<pre>
public class Factory {
	private static Factory instance = null;
	
	private static String PU;
	
	private EntityManagerFactory factory = null;
	
	private EntityManager em = null;  
	
	public Factory &#40;&#41; {
		try {
			factory = Persistence.createEntityManagerFactory&#40;PU&#41;;
		} catch &#40;Exception e&#41; {
			Debug.log&#40;"Exceção ao criar EntityManagerFactory. ", 
					"Mensagem: " + e.getMessage&#40;&#41;&#41;;	
			throw new RuntimeException&#40;e&#41;;  
		}
	}
   
    public EntityManager getEntityManager&#40;&#41; {  
        try {  
              
             em = factory.createEntityManager&#40;&#41;;  
             return em;  
               
        } catch &#40;Exception e&#41; {  
        	Debug.log&#40;"Exceção ao criar EntityManager. ", 
					"Mensagem: " + e.getMessage&#40;&#41;&#41;;	
             throw new RuntimeException&#40;e&#41;; 
            
         }  
    }  
       
    public static synchronized Factory getInstance&#40;&#41; {  
         if &#40;instance == null&#41; {  
             instance = new Factory&#40;&#41;;  
         }  
         return instance;  
     }

	public static void setPU&#40;String persistenceUnit&#41; {
		PU = persistenceUnit;
		
	}  
    
	public static void close&#40;&#41; {
		if &#40;instance.em != null&#41;
		if &#40;instance.em.isOpen&#40;&#41;&#41;
			instance.em.clear&#40;&#41;;
		
		if &#40;instance.factory != null&#41;
		if &#40;instance.factory.isOpen&#40;&#41;&#41;
			instance.factory.close&#40;&#41;;
	}

</pre>
		</div>


<b>LoginAction</b>
<span class="genmed"><b>Code:</b></span><br>
		<div style="overflow: auto; width: 100%;">
		<pre>
public class LoginAction extends BaseLoginAction {
	
	
	public String execute&#40;&#41; throws Exception {

		
		if &#40;!isPost&#40;&#41;&#41;
			return ERROR;
		Entidade e = null;
		try {
			
	  
			EntityManager manager = &#40;EntityManager&#41; input.getValue&#40;JPAFilter.KEY&#41;;
			
			e =  &#40;Entidade&#41; JpaDao.recuperarUm&#40;manager, "Entidade.recuperaEntidadePorLogin", 
	    							"login", username.toLowerCase&#40;&#41;&#41;;
	    	
	    	
	    	
	      	if &#40;e != null&#41; {
	      		if &#40;!e.getPassword&#40;&#41;.equalsIgnoreCase&#40;password&#41;&#41;
	    			{	
		    			addError&#40;"resultado", "Senha inválida."&#41;;
		    			
		    			return ERROR;
	    			}	
	      	} else {
	      		Debug.log&#40;"Exceção ao tentar efetuar Login &#40;Entidade retornou NULO&#41;.", "Username: " + username + " Password: "+ password&#41;;	      		
    				addError&#40;"resultado", "Login e/ou senha inválido&#40;s&#41;."&#41;;
    			
    			return ERROR;
	      	}
	      	
	      	//----
		} catch &#40;Exception ex&#41; {
			Debug.log&#40;"Exceção ao tentar efetuar Login &#40;Entidade retornou NULO&#41;.",
				"Mensagem: " + ex.getMessage&#40;&#41;&#41;;
			return ERROR;
		}

		
		try {
			setUserSession&#40;e&#41;;	
		} catch &#40;Exception ex &#41;{
			Debug.log&#40;"Exceção ao setar Usuário da sessão.", "ID Entidade: " + e.getId&#40;&#41; + " Username: "+ e.getLogin&#40;&#41;, "Mensagem: " + ex.getMessage&#40;&#41;&#41;;
		}
		
		

		return SUCCESS;
	}

}
</pre>
		</div>

Qualquer ajuda é bem vinda..

Obrigado

Marcos]]></description>
				<guid isPermaLink="true">http://forum.mentaframework.org/posts/list/2118.page#16119</guid>
				<link>http://forum.mentaframework.org/posts/list/2118.page#16119</link>
				<pubDate><![CDATA[Sat, 25 Oct 2008 11:57:13]]> GMT</pubDate>
				<author><![CDATA[ bermark]]></author>
			</item>
	</channel>
</rss>
