4

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>
joekarl
  • 2,058
  • 13
  • 23
  • seems fine to me. Make sure you are having a cleaned build and environment – Bozho Dec 07 '10 at 21:06
  • I have, it doesn't seem to help, only after I stop and start the server does it work. It's just weird to me that the app would stop working because of an unknown entity bean class when before the deploy it found it just fine. – joekarl Dec 07 '10 at 21:26
  • It looks like for some reason on a redeploy, the error happens if eclipselink doesn't have a successful logout. if I redeploy the app a couple of times, it will eventually get a successful logout and then the redeploy works. Any ideas? – joekarl Dec 07 '10 at 21:44
  • Can you please share your web.xml? – Mohamed Saligh Dec 08 '10 at 05:14

5 Answers5

2

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.

James
  • 19,367
  • 9
  • 72
  • 129
  • My guess is this was the problem. We've since moved to glassfish 3 and eclipselink and it has ceased to be an issue. – joekarl Jun 08 '11 at 13:49
1

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:

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.

Community
  • 1
  • 1
Mohamed Saligh
  • 11,048
  • 17
  • 61
  • 83
  • 1
    Actually, now I'm seeing issues if I redeploy on glassfish manually, so it can't be a netbeans issue. It seems to be following the pattern that if the jpa session doesn't get logged out properly (can see with eclipselink logging) then the app won't start the a new jpa session which causes the unknown entity exceptions. Unfortunately I can't force the app to logout of the jpa session at shutdown (I think glassfish takes care of this). Still can't think of what would cause this. – joekarl Dec 08 '10 at 18:27
  • Very interesting, I'm using Netbean6.9.1 with GlassFish v3 & EclipseLink and having exactly same issue. I just switched from toplink to eclipselink and this issue started... – Meow Feb 23 '11 at 09:45
1

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

akjoshi
  • 14,589
  • 13
  • 94
  • 116
Jan Volf
  • 11
  • 1
0

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

0

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.

joekarl
  • 2,058
  • 13
  • 23