Unknown entity bean class after hot deploy: netbea

2019-02-25 02:28发布

问题:

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>

回答1:

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.



回答2:

Your problem is quite interesting one. So, I just continue to read more about it. I found a thread at SO itself which is still do not have any solution JPA - Unknown entity bean class. Not only in SO, also some of the forums outside like:

  • "Unknown entity bean class" when accessing from a swing-app
  • EJB: Unknown entity bean class

After a while I found an another thread at SO itself "Java Persistance Issue"

Questioned & Answered by James itself:

So as the comments above suggest this seems to be an issue with the eclipse plug in for glassfish. I am having no problems when deploying the ear manually.

Thanks all for the help.

James

Finally, that sounds as an issue :) http://java.net/jira/browse/GLASSFISHPLUGINS-307

Hope, James message would help.



回答3:

Although it is not apparent from the posted code if this is the solution but symptoms are the same.

It seems to happen when creating entity manager from entity manager factory outside of the container. The factory needs to be closed on un-deploying. That is why it works only first time when deployed and not on redeploy. See: Unknown entity bean class issue with glassfish v3



回答4:

Turns out we weren't needing any of the JPA 2.0 features at this time and eclipselink support for glassfish v2 is a bit spotty. So the solution for us was to switch back to toplink and JPA 1.0 . Not the best solution but it solved our deployment issues. We'll be looking at eclipselink when we switch over to glassfish v3.



回答5:

I also got this problem in a web service that fetches data from database. I opted two solutions:- (1) Solution was to put a method in webservice like @PreDestroy public void destruct()==> Here i closed EntityManagerFactory (2) Introduced a listener ServletContextListener and closed open emf here also in case webservice method could not work due to any reason.

Because server-restart for re-deployment is not acceptable, I wanted to be on safer side,closing emf twice in case it remains open it has chance to get closed in listener.

Thanks Nitin