2014-09-02 81 views
0

我使用JPA 2.0,eclipselink 2.x和maven。這是我的persistence.xmlJPA與JTA有類加載器問題

<?xml version="1.0" encoding="UTF-8"?> 
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"> 
    <persistence-unit name="certifications" transaction-type="JTA"> 
     <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider> 
     <jta-data-source>jdbc/com/ni/ds_edata_soa_nontx</jta-data-source> 
     <class>com.ni.apps.engineering.certification.entities.NicdsCliCertificationStg</class> 
     <class>com.ni.apps.engineering.certification.entities.NicdsCliCertificationStgPK</class> 
     <class>com.ni.apps.engineering.certification.entities.NicdsCliUpMapping</class> 
     <properties>       
      <property name="javax.persistence.jdbc.password" value="ni"/> 
      <!--property name="javax.persistence.jdbc.user" value="NI"/--> 
      <property name="javax.persistence.jdbc.driver" value="oracle.jdbc.OracleDriver"/> 
      <property name="eclipselink.logging.level.sql" value="FINE"/>  
     </properties>  
    </persistence-unit> 
</persistence> 

我有這個AbstractFacade

public abstract class AbstractFacade { 

    @PersistenceUnit(unitName = "certifications") 
    private static EntityManagerFactory emf; 

    private EntityManager em; 

    /** 
    * Gets the entity manager 
    * @return 
    */ 
    protected EntityManager getEntityManager(){ 
     if(emf == null){ 
      emf = Persistence.createEntityManagerFactory("certifications"); 
     } 
     if(em == null){ 
      em = emf.createEntityManager(); 
     } 
     return em; 
    } 

} 

而且我這是怎麼實現它

public class CertificationFacade extends AbstractFacade{ 

    /** 
    * Gets the certifications for the paramenter upId 
    * @param upId the upId 
    * @return the certifications 
    * @throws CertificationException 
    */ 
    public List<NicdsCliCertificationStg> getCertificationsByUpId(String upId) 
      throws CertificationException { 
     String stringQuery = new StringBuilder(
       "select c from NicdsCliCertificationStg c, NicdsCliUpMapping d where c.id.contactsId = d.contactsId and d.profileId =") 
       .append(upId).toString(); 
     try { 
      TypedQuery<NicdsCliCertificationStg> query = getEntityManager().createQuery(stringQuery, 
        NicdsCliCertificationStg.class);    
      return query.getResultList(); 
     } catch (Exception e) { 
      throw new CertificationException(
        CertificationConstants.INTERNAL_ERROR_MESSAGE, e); 
     } 
    } 
} 

這是DAO

public final class CertificationDAO { 

    private CertificationDAO(){} 

    /** 
    **Gets the certifications for the requested upId 
    * @param upId the upId 
    * @return the certifications 
    * @throws CertificationException 
    */ 
    public static Certifications getCertificationByUpId(String upId) throws CertificationException{ 
     Certifications response = new Certifications(); 
     List<NicdsCliCertificationStg> certifications = new CertificationFacade().getCertificationsByUpId(upId); 
     CertificationType newCertification = new CertificationType(); 
     for(NicdsCliCertificationStg cert : certifications){ 
      newCertification.setAlternateEmail(cert.getAlternateEmail()); 
      newCertification.setCertificationName(cert.getId().getCertName()); 
      newCertification.setContactId((int)cert.getId().getContactsId()); 
      newCertification.setFirstName(cert.getFirstName()); 
      newCertification.setLastName(cert.getLastName()); 
      newCertification.setPrimaryEmail(cert.getPrimaryEmail()); 
      newCertification.setStatus(cert.getCertStatus()); 
      response.getCertification().add(newCertification); 
     } 
     return response;   
    } 
} 

的當我嘗試迭代時會導致異常通過列表的速度。我得到一個ClassCastException。我一直在閱讀,這是由兩個可能的原因造成的:1)類在類路徑中複製(這不是我的情況),2)同時有2個不同的類加載器。當我將應用程序重新部署到我的weblogic時,也會發生此異常。看起來垃圾收集器並沒有足夠快地回收舊的類加載器,當我運行該應用程序時,我正在同時處理兩個類加載器,導致classcast異常。我不明白的是,因爲我在persistence.xml中使用了JTA事務類型,所以應該自動處理EntityManagerFactory的生命週期。一種選擇是自己關閉工廠,但我更感興趣的是瞭解JTA爲什麼不爲我處理這個問題。謝謝!

- 編輯 - 堆棧跟蹤

java.lang.ClassCastException: com.ni.apps.engineering.certification.entities.NicdsCliCertificationStg 
    at com.ni.apps.engineering.certification.dao.CertificationDAO.getCertificationByUpId(CertificationDAO.java:25) 
    at com.ni.apps.engineering.certification.rest.implementation.CertificationService.getCertificationByUpId(CertificationService.java:28) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 
    at java.lang.reflect.Method.invoke(Method.java:597) 
    at com.sun.jersey.spi.container.JavaMethodInvokerFactory$1.invoke(JavaMethodInvokerFactory.java:60) 
    at com.sun.jersey.server.impl.model.method.dispatch.AbstractResourceMethodDispatchProvider$ResponseOutInvoker._dispatch(AbstractResourceMethodDispatchProvider.java:205) 
    at com.sun.jersey.server.impl.model.method.dispatch.ResourceJavaMethodDispatcher.dispatch(ResourceJavaMethodDispatcher.java:75) 
    at com.sun.jersey.server.impl.uri.rules.HttpMethodRule.accept(HttpMethodRule.java:302) 
    at com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:147) 
    at com.sun.jersey.server.impl.uri.rules.ResourceClassRule.accept(ResourceClassRule.java:108) 
    at com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:147) 
    at com.sun.jersey.server.impl.uri.rules.RootResourceClassesRule.accept(RootResourceClassesRule.java:84) 
    at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1511) 
    at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1442) 
    at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1391) 
    at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1382) 
    at com.sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.java:416) 
    at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:538) 
    at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:717) 
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:821) 
    at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:227) 
    at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:125) 
    at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:301) 
    at weblogic.servlet.internal.TailFilter.doFilter(TailFilter.java:27) 
    at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:57) 
    at com.ni.apps.engineering.certification.filter.ConfigurableRepRestServletFilter.doFilter(ConfigurableRepRestServletFilter.java:139) 
    at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:57) 
    at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.wrapRun(WebAppServletContext.java:3730) 
    at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:3696) 
    at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321) 
    at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:120) 
    at weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppServletContext.java:2273) 
    at weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletContext.java:2179) 
    at weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.java:1490) 
    at weblogic.work.ExecuteThread.execute(ExecuteThread.java:256) 
    at weblogic.work.ExecuteThread.run(ExecuteThread.java:221) 
+0

請發佈堆棧跟蹤,同時CertificationFacade代碼在帖子中重複...它缺少道代碼 – fmodos 2014-09-02 16:20:19

+0

哎呀,對不起,剛纔注意到。在上面。 – Nacho321 2014-09-02 16:21:40

+0

它看起來很奇怪,你調試過這段代碼嗎?如果它沒有在weblogic中部署,會發生這種錯誤嗎?我的意思是你是否嘗試使用基本的java main運行這段代碼?我建議你這樣做,以減少錯誤範圍 – fmodos 2014-09-02 16:39:43

回答

0

所以,這是我的固定它。

import javax.servlet.ServletContextEvent; 
import javax.servlet.ServletContextListener; 

import com.ni.apps.engineering.certification.controller.AbstractFacade; 

public class ApplicationListener implements ServletContextListener { 

    @Override 
    public void contextDestroyed(ServletContextEvent arg0) { 
     AbstractFacade.closeFactory(); 
    } 

    @Override 
    public void contextInitialized(ServletContextEvent arg0) { 

    } 

} 

這樣,每次我重新部署應用程序,我都確保我創建的工廠已關閉。

CNC中 只是爲了說清楚,創建監聽器類後,我必須將監聽器添加到web.xml這樣

<listener> 
    <listener-class>com.ni.apps.engineering.certification.filter.ApplicationListener</listener-class> 
</listener> 

的closeFactory()只是做emf.close( )在驗證emf不是null後。