When I deploy my app, it works perfectly until I make a change, save, and netbeans hot deploys the application. At this point I get an unknown entity bean class error on a class that has the @entity and it’s included in my persistence.xml. When this happens, anything dealing with jpa stops working. Only if I restart the server will my jpa stuff start working again.
If I turn deploy on save off in my project and I only manually save and deploy I get the same results.
Is this just a netbeans/glassfish error? Or is there something wrong with my jpa setup?
Exception
java.lang.IllegalArgumentException: Unknown entity bean class: class amc.nase.idms.persistence.model.SecSession, please verify that this class has been marked with the @Entity annotation.
at org.eclipse.persistence.internal.jpa.EntityManagerImpl.find(EntityManagerImpl.java:592)
at org.eclipse.persistence.internal.jpa.EntityManagerImpl.find(EntityManagerImpl.java:476)
at amc.nase.idms.persistence.controllers.SecSessionJpaController.findSecSession(SecSessionJpaController.java:134)
at amc.nase.idms.services.SecurityServiceHelper.validateSession(SecurityServiceHelper.java:106)
at amc.nase.idms.services.SecurityService.validateSession(SecurityService.java:78)
at amc.nase.idms.web.extensions.SecurityInterceptor.intercept(SecurityInterceptor.java:64)
at net.sourceforge.stripes.controller.ExecutionContext.proceed(ExecutionContext.java:155)
at net.sourceforge.stripes.controller.BeforeAfterMethodInterceptor.intercept(BeforeAfterMethodInterceptor.java:113)
Entity
import java.io.Serializable;
import java.util.Date;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
@Entity
@Table(name = "SEC_SESSION",schema = "APPLOCK")
@NamedQueries({
@NamedQuery(name = "SecSession.findAll", query = "SELECT s FROM SecSession s"),
@NamedQuery(name = "SecSession.findBySessionid", query = "SELECT s FROM SecSession s WHERE s.sessionid = :sessionid"),
@NamedQuery(name = "SecSession.findByOrgid", query = "SELECT s FROM SecSession s WHERE s.orgid = :orgid"),
@NamedQuery(name = "SecSession.findByConnecttime", query = "SELECT s FROM SecSession s WHERE s.connecttime = :connecttime"),
@NamedQuery(name = "SecSession.findByConnectip", query = "SELECT s FROM SecSession s WHERE s.connectip = :connectip")})
public class SecSession implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@Column(name = "SESSIONID")
private String sessionid;
@Basic(optional = false)
@Column(name = "ORGID")
private Integer orgid;
@Basic(optional = false)
@Column(name = "CONNECTTIME")
@Temporal(TemporalType.TIMESTAMP)
private Date connecttime;
@Basic(optional = false)
@Column(name = "CONNECTIP")
private String connectip;
public SecSession() {
}
public SecSession(String sessionid) {
this.sessionid = sessionid;
}
public SecSession(String sessionid, Integer orgid, Date connecttime, String connectip) {
this.sessionid = sessionid;
this.orgid = orgid;
this.connecttime = connecttime;
this.connectip = connectip;
}
public String getSessionid() {
return sessionid;
}
public void setSessionid(String sessionid) {
this.sessionid = sessionid;
}
public Integer getOrgid() {
return orgid;
}
public void setOrgid(Integer orgid) {
this.orgid = orgid;
}
public Date getConnecttime() {
return connecttime;
}
public void setConnecttime(Date connecttime) {
this.connecttime = connecttime;
}
public String getConnectip() {
return connectip;
}
public void setConnectip(String connectip) {
this.connectip = connectip;
}
@Override
public int hashCode() {
int hash = 0;
hash += (sessionid != null ? sessionid.hashCode() : 0);
return hash;
}
@Override
public boolean equals(Object object) {
if (!(object instanceof SecSession)) {
return false;
}
SecSession other = (SecSession) object;
if ((this.sessionid == null && other.sessionid != null) || (this.sessionid != null && !this.sessionid.equals(other.sessionid))) {
return false;
}
return true;
}
@Override
public String toString() {
return "gov.faa.nase.security.persistence.SecSession[sessionid=" + sessionid + "]";
}
public SecSessionTO transfer(){
SecSessionTO to = new SecSessionTO();
to.setConnectIP(connectip);
to.setConnectTime(connecttime);
to.setOrgId(orgid);
to.setSessionId(sessionid);
return to;
}
}
Persistence xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.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_1_0.xsd">
<persistence-unit name="iDMSPU" transaction-type="JTA">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<jta-data-source>jdbc/dms</jta-data-source>
<class>amc.nase.idms.persistence.model.Org</class>
<class>amc.nase.idms.persistence.model.SecApp</class>
<class>amc.nase.idms.persistence.model.SecPermission</class>
<class>amc.nase.idms.persistence.model.SecRole</class>
<class>amc.nase.idms.persistence.model.SecSession</class>
<class>amc.nase.idms.persistence.model.SecUserRole</class>
<class>amc.nase.idms.persistence.model.TurAccessCodes</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<properties/>
</persistence-unit>
</persistence>
UPDATE
Web XML
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<context-param>
<param-name>IOCInjector.PACKAGE</param-name>
<param-value>amc.nase.idms.services</param-value>
</context-param>
<listener>
<listener-class>amc.nase.idms.web.IOCInitializer</listener-class>
</listener>
<filter>
<display-name>Stripes Filter</display-name>
<filter-name>StripesFilter</filter-name>
<filter-class>net.sourceforge.stripes.controller.StripesFilter</filter-class>
<init-param>
<param-name>ActionResolver.Packages</param-name>
<param-value>amc.nase.idms.web.actions</param-value>
</init-param>
<init-param>
<param-name>Extension.Packages</param-name>
<param-value>amc.nase.idms.web.extensions</param-value>
</init-param>
<init-param>
<param-name>Configuration.Class</param-name>
<param-value>amc.nase.idms.web.extensions.IOCRuntimeConfiguration</param-value>
</init-param>
<init-param>
<param-name>ActionBeanContextFactory.Class</param-name>
<param-value>amc.nase.idms.web.extensions.IDMSActionBeanContextFactory</param-value>
</init-param>
<init-param>
<param-name>ActionResolver.Class</param-name>
<param-value>amc.nase.idms.web.extensions.IDMSActionResolver</param-value>
</init-param>
</filter>
<filter>
<description>Dynamically maps URLs to ActionBeans.</description>
<display-name>Stripes Dynamic Mapping Filter</display-name>
<filter-name>DynamicMappingFilter</filter-name>
<filter-class>net.sourceforge.stripes.controller.DynamicMappingFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>StripesFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
<filter-mapping>
<filter-name>DynamicMappingFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
<dispatcher>INCLUDE</dispatcher>
</filter-mapping>
<session-config>
<session-timeout>
30
</session-timeout>
</session-config>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<resource-ref>
<res-ref-name>jdbc/dms</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
<res-sharing-scope>Shareable</res-sharing-scope>
</resource-ref>
<resource-ref>
<res-ref-name>jdbc/harv</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
<res-sharing-scope>Shareable</res-sharing-scope>
</resource-ref>
</web-app>
The issue is the old persistence unit with references to the old classes is remaining after your redeploy. Ensure the old EntityManagerFactory is getting closed. Glassfish should handle this for any managed factories such as in a SessionBean, but if you are managing your own factories you need to ensure these are closed.