mysql - EJB 未知的抽象模式,但它存在于数据库中

标签 mysql jpa ejb glassfish-4

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

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

我在 Google 或这里发现的一些问题是通过将类添加到持久化单元来解决的,我做到了,但它仍然抛出异常。

这是我的 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

如果有人知道,那将非常有帮助! 抱歉有些英语错误,这不是我的母语...

最佳答案

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

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

关于mysql - EJB 未知的抽象模式,但它存在于数据库中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17896574/

相关文章:

php - Ignited Datatables 在连接表时获取 id

php - 如何在php中为选择查询中的每个组插入一个空行

java - 应该在 equals/hashCode/toString 中使用 @Transient 属性吗?

java - hibernate/jpa double OneToOne 与一个实体的双向关系

java - 如何在 JSF 中填充数据

php - 如何: executing a block of code every 24 hours in a server?

mysql - 没有order by子句时先返回哪个字段?

java - 我如何告诉 Hibernate 不要为此实体创建表?

java - 使用 Java 9 运行应用程序,模块 java.base 不是 "opens java.io"

java - 无法使用 RMI 客户端从 DBMS 恢复数据