【问题标题】:EJB unknown abstrat schema but it exists in the DBEJB 未知的抽象模式,但它存在于数据库中
【发布时间】:2013-07-27 14:55:35
【问题描述】:

我在这个问题上被阻止了好几个小时,我不明白这个问题,因为它适用于我项目的另一个实体。 我在 Eclipse IDE 中使用 Glassfish 4、JPA 2 和 EJB 3 创建了一个 Java EE 项目。 我正在使用 mysql 数据库进行存储。

我创建了一个名为 Company 的实体 bean 和一个 DAO 来管理它。我做了所有需要的工作,而且效果很好。 问题是我对另一个名为 Newsletter 的实体 bean 做了完全相同的事情,但是这个不起作用。 Java 抛出一个 EJBException,告诉我抽象模式是未知的,但它存在于数据库中。 表 company 和 newsletter 在同一个数据库中,所以我对它们都使用了相同的持久化单元。

我在 Google 或此处找到的一些问题通过将类添加到 persitence-unit 来解决,我做到了,但它仍然抛出异常。

这是我的 NEWSLETTER 表格:

    +--------------+--------------+------+-----+---------+----------------+
    | Field        | Type         | Null | Key | Default | Extra          |
    +--------------+--------------+------+-----+---------+----------------+
    | idNewsletter | int(11)      | NO   | PRI | NULL    | auto_increment |
    | firstname    | varchar(100) | NO   |     | NULL    |                |
    | lastname     | varchar(100) | NO   |     | NULL    |                |
    | email        | varchar(255) | NO   |     | NULL    |                |
    +--------------+--------------+------+-----+---------+----------------+

我的 bean 时事通讯:

    @Entity
    public class Newsletter {

        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private Long idNewsletter;

        @Column(name="firstname")
        private String firstname;

        @Column(name="lastname")
        private String lastname;

        @Column(name="email")
        private String email;

    }

这是我的 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="2lifedb_PU" transaction-type="JTA">
    <jta-data-source>jdbc/bonecp_resource</jta-data-source>
    <class>com.twolife.beans.User</class>
    <class>com.twolife.beans.Company</class>
    <class>com.twolife.beans.Office</class>
    <class>com.twolife.beans.BankDetails</class>
    <class>com.twolife.beans.Logo</class>
    <class>com.twolife.beans.Newsletter</class>
    <properties>
        <property name="eclipselink.logging.level.sql" value="FINE"/>
        <property name="eclipselink.logging.parameters" value="true"/>
    </properties>
</persistence-unit>

还有 DAO 类:

    @Stateless
    public class DAONewsletter {

        private static final String SQL_SELECT_NEWSLETTER = "SELECT n FROM NEWSLETTER n WHERE n.email = :email";

        @PersistenceContext(unitName="2lifedb_PU")
        private EntityManager em;

        public void create(Newsletter newsletter) throws DAOException {
            try {
                em.persist(newsletter);
            } catch (Exception e) {
                throw new DAOException(e);
            }
        }

        public Newsletter find(String email) throws DAOException {
            Newsletter newsletter = new Newsletter();

            Query query = em.createQuery(SQL_SELECT_NEWSLETTER);
            query.setParameter("email", email);

            try {
                newsletter = (Newsletter) query.getSingleResult();
            } catch (NoResultException e) {
                return null;
            } catch (Exception e) {
                throw new DAOException(e);
            }

            return newsletter;
       }
    }

最后,这是我的异常的堆栈跟踪:

    Caused by: java.lang.IllegalArgumentException: An exception occurred while creating a query in EntityManager: 
    Exception Description: Problem compiling [SELECT n FROM NEWSLETTER n WHERE n.email = :email]. 
    [14, 24] The abstract schema type 'NEWSLETTER' is unknown.
    [33, 40] The state field path 'n.email' cannot be resolved to a valid type.
        at org.eclipse.persistence.internal.jpa.EntityManagerImpl.createQuery(EntityManagerImpl.java:1585)
        at com.sun.enterprise.container.common.impl.EntityManagerWrapper.createQuery(EntityManagerWrapper.java:456)
        at com.twolife.dao.DAONewsletter.find(DAONewsletter.java:30)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:606)
        at org.glassfish.ejb.security.application.EJBSecurityManager.runMethod(EJBSecurityManager.java:1081)
        at org.glassfish.ejb.security.application.EJBSecurityManager.invoke(EJBSecurityManager.java:1153)
        at com.sun.ejb.containers.BaseContainer.invokeBeanMethod(BaseContainer.java:4695)
        at com.sun.ejb.EjbInvocation.invokeBeanMethod(EjbInvocation.java:630)
        at com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:822)
        at com.sun.ejb.EjbInvocation.proceed(EjbInvocation.java:582)
        at com.sun.ejb.containers.interceptors.SystemInterceptorProxy.doCall(SystemInterceptorProxy.java:163)
        at com.sun.ejb.containers.interceptors.SystemInterceptorProxy.aroundInvoke(SystemInterceptorProxy.java:140)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:606)
        at com.sun.ejb.containers.interceptors.AroundInvokeInterceptor.intercept(InterceptorManager.java:883)
        at com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:822)
        at com.sun.ejb.containers.interceptors.InterceptorManager.intercept(InterceptorManager.java:369)
        at com.sun.ejb.containers.BaseContainer.__intercept(BaseContainer.java:4667)
        at com.sun.ejb.containers.BaseContainer.intercept(BaseContainer.java:4655)
        at com.sun.ejb.containers.EJBLocalObjectInvocationHandler.invoke(EJBLocalObjectInvocationHandler.java:212)
        ... 36 more
    Caused by: Exception [EclipseLink-0] (Eclipse Persistence Services - 2.5.0.v20130507-3faac2b): org.eclipse.persistence.exceptions.JPQLException
    Exception Description: Problem compiling [SELECT n FROM NEWSLETTER n WHERE n.email = :email]. 
    [14, 24] The abstract schema type 'NEWSLETTER' is unknown.
    [33, 40] The state field path 'n.email' cannot be resolved to a valid type.
        at org.eclipse.persistence.internal.jpa.jpql.HermesParser.buildException(HermesParser.java:155)
        at org.eclipse.persistence.internal.jpa.jpql.HermesParser.validate(HermesParser.java:347)
        at org.eclipse.persistence.internal.jpa.jpql.HermesParser.populateQueryImp(HermesParser.java:278)
        at org.eclipse.persistence.internal.jpa.jpql.HermesParser.buildQuery(HermesParser.java:163)
        at org.eclipse.persistence.internal.jpa.EJBQueryImpl.buildEJBQLDatabaseQuery(EJBQueryImpl.java:142)
        at org.eclipse.persistence.internal.jpa.EJBQueryImpl.buildEJBQLDatabaseQuery(EJBQueryImpl.java:116)
        at org.eclipse.persistence.internal.jpa.EJBQueryImpl.<init>(EJBQueryImpl.java:102)
        at org.eclipse.persistence.internal.jpa.EJBQueryImpl.<init>(EJBQueryImpl.java:86)
        at org.eclipse.persistence.internal.jpa.EntityManagerImpl.createQuery(EntityManagerImpl.java:1583)
        ... 60 more

如果任何人有想法,那将非常有帮助! 对不起,有些英语错误,这不是我的母语......

【问题讨论】:

    标签: mysql jpa ejb glassfish-4


    【解决方案1】:

    我在wildfly 10.0 和eclipselink 2.6 中遇到了同样的问题。

    我解决了将以下系统属性添加到standalone.xml 文件

    <?xml version='1.0' encoding='UTF-8'?>
    
    <server xmlns="urn:jboss:domain:4.2">
    <system-properties>
        <property name="eclipselink.archive.factory" value="org.jipijapa.eclipselink.JBossArchiveFactoryImpl"/>
    </system-properties>
    ...
    </server>
    

    【讨论】:

      【解决方案2】:

      em.createQuery() 需要 JPQL 查询,而不是 SQL 查询。 SQL 和 JPQL 不是同一种语言。 SQL 适用于表和列。 JPQL 与实体、字段/属性和关联一起工作。永远不要使用表名和列名。语法相似,但不同。

      您的实体名为Newsletter,但您的查询使用NEWSLETTER。类名区分大小写。

      【讨论】:

      • 非常感谢!!我不知道实体管理器可以使用 JPQL 语法而没有 SQL 语法。这已经解决了!!
      猜你喜欢
      • 2019-01-22
      • 1970-01-01
      • 2012-05-13
      • 1970-01-01
      • 2016-05-31
      • 1970-01-01
      • 1970-01-01
      • 2019-12-30
      • 1970-01-01
      相关资源
      最近更新 更多