我正在使用JPA 2.0,eclipselink 2.x和maven。这是我的persistence.xml
<?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时,也会发生此异常。似乎垃圾收集器没有足够快地回收旧的类加载器,当我运行应用程序时,我同时处理两个类加载器,导致了类转换异常。我不明白的是,因为我在我的persistence.xml中使用JTA事务类型,所以应该自动处理EntityManagerFactory的生命周期。一个选择是自己关闭工厂,但我更感兴趣的是为什么不是JTA为我处理这个问题。谢谢!
- EDIT-- 栈跟踪
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 :(得分: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中 为了说清楚,在创建了Listener类之后,我必须像这样添加侦听器到web.xml
<listener>
<listener-class>com.ni.apps.engineering.certification.filter.ApplicationListener</listener-class>
</listener>
在验证emf不为null之后,closeFactory()只执行emf.close()。