【问题标题】:Unknown entity bean class after hot deploy: netbeans 6.9 + glassfish 2.1 + eclipselink jpa 2.0热部署后未知实体 bean 类:netbeans 6.9 + glassfish 2.1 + eclipselink jpa 2.0
【发布时间】:2010-12-07 21:02:27
【问题描述】:

当我部署我的应用程序时,它运行良好,直到我进行更改、保存和 netbeans 热部署应用程序。此时,我在具有@entity 的类上收到未知实体bean 类错误,它包含在我的persistence.xml 中。发生这种情况时,任何与 jpa 打交道的东西都会停止工作。只有重新启动服务器,我的 jpa 才能重新开始工作。

如果我在我的项目中将部署打开保存关闭并且我只手动保存和部署,我会得到相同的结果。

这只是 netbeans/glassfish 错误吗?还是我的 jpa 设置有问题?

异常

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)

实体

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;
    }
}

持久化 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>

更新

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>

【问题讨论】:

  • 对我来说似乎很好。确保你有一个干净的构建和环境
  • 我有,它似乎没有帮助,只有在我停止并启动服务器后它才能工作。对我来说很奇怪,应用程序会因为未知的实体 bean 类而停止工作,而在部署之前它发现它很好。
  • 看起来由于某种原因在重新部署时,如果 eclipselink 没有成功注销,则会发生错误。如果我重新部署应用程序几次,它最终会成功注销,然后重新部署工作。有什么想法吗?
  • 你能分享你的 web.xml 吗?

标签: java jpa jakarta-ee eclipselink netbeans-6.9


【解决方案1】:

问题是在您重新部署后,引用旧类的旧持久性单元仍然存在。确保旧的 EntityManagerFactory 正在关闭。 Glassfish 应该为任何托管工厂(例如在 SessionBean 中)处理此问题,但如果您管理自己的工厂,则需要确保这些工厂已关闭。

【讨论】:

  • 我猜这就是问题所在。从那以后,我们转向 glassfish 3 和 eclipselink,它不再是一个问题。
【解决方案2】:

你的问题很有趣。所以,我只是继续阅读更多关于它的信息。我在 SO 本身找到了一个线程,它仍然没有任何解决方案JPA - Unknown entity bean class。不仅在SO,还有一些外面的论坛,比如:

过了一会儿,我在 SO 本身发现了另一个帖子“Java Persistance Issue

James 本人提问和回答:

所以正如上面的 cmets 所建议的那样 似乎是日食的问题 插入玻璃鱼。我没有 部署耳朵时的问题 手动。

感谢大家的帮助。

詹姆斯

最后,这听起来是个问题 :) http://java.net/jira/browse/GLASSFISHPLUGINS-307

希望詹姆斯的信息会有所帮助。

【讨论】:

  • 实际上,如果我手动在 glassfish 上重新部署,现在我会看到问题,所以它不可能是 netbeans 问题。似乎遵循以下模式:如果 jpa 会话没有正确注销(可以通过 eclipselink 日志查看),那么应用程序将不会启动新的 jpa 会话,这会导致未知实体异常。不幸的是,我不能强制应用程序在关闭时注销 jpa 会话(我认为 glassfish 会处理这个问题)。还是想不出是什么原因造成的。
  • 非常有趣,我正在使用带有 GlassFish v3 和 EclipseLink 的 Netbean6.9.1,并且遇到了完全相同的问题。我刚从 toplink 切换到 eclipselink,这个问题就开始了……
【解决方案3】:

虽然从发布的代码中看不出这是否是解决方案,但症状是相同的。

从容器外部的实体管理器工厂创建实体管理器时似乎会发生这种情况。工厂需要在取消部署时关闭。这就是为什么它只在第一次部署时才起作用,而不是在重新部署时起作用。见:Unknown entity bean class issue with glassfish v3

【讨论】:

    【解决方案4】:

    事实证明,我们此时不需要任何 JPA 2.0 功能,并且 eclipselink 对 glassfish v2 的支持有点参差不齐。所以我们的解决方案是切换回 toplink 和 JPA 1.0 。不是最好的解决方案,但它解决了我们的部署问题。当我们切换到 glassfish v3 时,我们将研究 eclipselink。

    【讨论】:

      【解决方案5】:

      我在从数据库获取数据的 Web 服务中也遇到了这个问题。 我选择了两种解决方案:- (1)解决方案是在网络服务中放置一个方法,例如 @PreDestroy public void destruct()==> 这里我关闭了 EntityManagerFactory (2) 在这里引入了一个监听器ServletContextListener并关闭了open emf,以防万一webservice方法由于任何原因无法工作。

      因为重新部署的服务器重新启动是不可接受的,所以我想更安全一点,关闭 emf 两次以防它保持打开状态,它有机会在侦听器中关闭。

      谢谢 尼丁

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-01-03
        相关资源
        最近更新 更多