即使看起来像一个简单的JPQL调用,JPA也无法按预期工作

时间:2018-09-19 03:14:07

标签: java docker eclipselink tomee java-10

即使看起来像一个简单的JPQL调用,JPA也无法按预期工作:

SELECT e FROM Employee e

...但是,获取此异常(GET操作后从系统日志中获取)...

注意EL警告:“在实体搜索过程中可能找不到模型类” ...

-
-
-
[EL Info]: 2018-09-19 12:21:37.142--ServerSession(301360221)--Thread(Thread[http-nio-8080-exec-1,5,main])--/file:/usr/local/apache-tomee-plume-7.0.5/webapps/MyRestSvc/WEB-INF/classes/_DB2JPA login successful
[EL Warning]: 2018-09-19 12:21:37.144--ServerSession(301360221)--Thread(Thread[http-nio-8080-exec-1,5,main])--Problem while registering MBean: java.lang.NullPointerException
[EL Warning]: 2018-09-19 12:21:37.156--Thread(Thread[http-nio-8080-exec-1,5,main])--The collection of metamodel types is empty. Model classes may not have been found during entity search for Java SE and some Java EE container managed persistence units.  Please verify that your entity classes are referenced in persistence.xml using either <class> elements or a global <exclude-unlisted-classes>false</exclude-unlisted-classes> element
java.lang.IllegalArgumentException: An exception occurred while creating a query in EntityManager: 
Exception Description: Problem compiling [SELECT e FROM Employee e]. 
[14, 22] The abstract schema type 'Employee' is unknown.
    at org.eclipse.persistence.internal.jpa.EntityManagerImpl.createQuery(EntityManagerImpl.java:1743)
    at org.eclipse.persistence.internal.jpa.EntityManagerImpl.createQuery(EntityManagerImpl.java:1764)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:564)
    at org.apache.openejb.persistence.JtaEntityManager.createQuery(JtaEntityManager.java:387)
    at org.apache.openejb.persistence.JtaEntityManager.typedProxyIfNoTx(JtaEntityManager.java:382)
    at org.apache.openejb.persistence.JtaEntityManager.createQuery(JtaEntityManager.java:454)
    at aaa.bbb.ccc.war.MyRestSvc.get(MyRestSvc.java:42)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
-
-
-

任何有助于解决此问题的想法/建议将不胜感激。想知道EclipseLink版本2.7.1是否存在某些不兼容性,以及如何通过Eclipse(光子)ide生成模型类。

我正在使用与db2express-c捆绑在一起的db2sampl数据库...

这是tomee.xml声明资源...

<?xml version="1.0" encoding="UTF-8"?> 
<tomee>
    <Resource id="jdbc/sample" type="javax.sql.DataSource">
        driverClassName com.ibm.db2.jcc.DB2Driver
        jdbcDriverType  4
        url         jdbc:db2://localhost:50000/SAMPLE
        username        db2inst1
        password        db2inst1-pwd
    </Resource>
</tomee>

这是persistence.xml ...

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1"
    xmlns="http://xmlns.jcp.org/xml/ns/persistence"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
    <persistence-unit name="DB2JPA">
        <jta-data-source>jdbc/SAMPLE</jta-data-source>
        <class>aaa.bbb.ccc.model.Department</class>
        <class>aaa.bbb.ccc.model.Employee</class>
        <class>aaa.bbb.ccc.model.Staff</class>      
        <exclude-unlisted-classes>false</exclude-unlisted-classes>      
        <properties>
            <property name="eclipselink.logging.level" value="FINE" />
        </properties>
    </persistence-unit>
</persistence>

以下是模型类(使用Eclipse创建:从表生成的实体)...

Employee.java ...

package aaa.bbb.ccc.model;

import java.io.Serializable;
import javax.persistence.*;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;


/**
 * The persistent class for the EMPLOYEE database table.
 * 
 */
@Entity
@Table(name="EMPLOYEE")
@NamedQuery(name="Employee.findAll", query="SELECT e FROM Employee e")
public class Employee implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    @Column(unique=true, nullable=false, length=6)
    private String empno;

    @Temporal(TemporalType.DATE)
    private Date birthdate;

    @Column(precision=9, scale=2)
    private BigDecimal bonus;

    @Column(name="\"COMM\"", precision=9, scale=2)
    private BigDecimal comm;

    @Column(nullable=false)
    private short edlevel;

    @Column(nullable=false, length=12)
    private String firstnme;

    @Temporal(TemporalType.DATE)
    private Date hiredate;

    @Column(length=8)
    private String job;

    @Column(nullable=false, length=15)
    private String lastname;

    @Column(length=1)
    private String midinit;

    @Column(length=4)
    private String phoneno;

    @Column(precision=9, scale=2)
    private BigDecimal salary;

    @Column(length=1)
    private String sex;

    //bi-directional many-to-one association to Department
    @OneToMany(mappedBy="employee")
    private List<Department> departments;

    //bi-directional many-to-one association to Department
    @ManyToOne
    @JoinColumn(name="WORKDEPT")
    private Department department;

    public Employee() {
    }

    public String getEmpno() {
        return this.empno;
    }

    public void setEmpno(String empno) {
        this.empno = empno;
    }

    public Date getBirthdate() {
        return this.birthdate;
    }

    public void setBirthdate(Date birthdate) {
        this.birthdate = birthdate;
    }

    public BigDecimal getBonus() {
        return this.bonus;
    }

    public void setBonus(BigDecimal bonus) {
        this.bonus = bonus;
    }

    public BigDecimal getComm() {
        return this.comm;
    }

    public void setComm(BigDecimal comm) {
        this.comm = comm;
    }

    public short getEdlevel() {
        return this.edlevel;
    }

    public void setEdlevel(short edlevel) {
        this.edlevel = edlevel;
    }

    public String getFirstnme() {
        return this.firstnme;
    }

    public void setFirstnme(String firstnme) {
        this.firstnme = firstnme;
    }

    public Date getHiredate() {
        return this.hiredate;
    }

    public void setHiredate(Date hiredate) {
        this.hiredate = hiredate;
    }

    public String getJob() {
        return this.job;
    }

    public void setJob(String job) {
        this.job = job;
    }

    public String getLastname() {
        return this.lastname;
    }

    public void setLastname(String lastname) {
        this.lastname = lastname;
    }

    public String getMidinit() {
        return this.midinit;
    }

    public void setMidinit(String midinit) {
        this.midinit = midinit;
    }

    public String getPhoneno() {
        return this.phoneno;
    }

    public void setPhoneno(String phoneno) {
        this.phoneno = phoneno;
    }

    public BigDecimal getSalary() {
        return this.salary;
    }

    public void setSalary(BigDecimal salary) {
        this.salary = salary;
    }

    public String getSex() {
        return this.sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public List<Department> getDepartments() {
        return this.departments;
    }

    public void setDepartments(List<Department> departments) {
        this.departments = departments;
    }

    public Department addDepartment(Department department) {
        getDepartments().add(department);
        department.setEmployee(this);

        return department;
    }

    public Department removeDepartment(Department department) {
        getDepartments().remove(department);
        department.setEmployee(null);

        return department;
    }

    public Department getDepartment() {
        return this.department;
    }

    public void setDepartment(Department department) {
        this.department = department;
    }

}

Department.java ...

(removed for space - can provide on request)

Staff.java ...

(removed for space - can provide on request)

这是REST服务-只是GET方法(为简单起见)...

package aaa.bbb.ccc.war;

import java.util.List;

import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.UriInfo;

import aaa.bbb.ccc.model.Employee;

@Stateless
@Path("/employeeList")
public class MyRestSvc {

    @PersistenceContext(unitName = "DB2JPA")
    EntityManager em;

    @Context
    UriInfo uriInfo;

    public MyRestSvc() {
    }


    @GET
    @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
    public List<Employee> get(@Context javax.servlet.http.HttpServletRequest request) {

        em.getEntityManagerFactory().getCache().evictAll(); // Invalidate all objects in the cache

        List<Employee> eList = null;

        try {
            eList = em.createQuery("SELECT e FROM Employee e").getResultList();

        } catch (Exception e) {
            e.printStackTrace();
            throw e;
        }

        return eList;
    }

}

这是Tomee启动日志...

(removed for space - can provide on request)    

这是对GET操作的系统日志输出/反应...

[EL Info]: 2018-09-19 07:05:43.756--ServerSession(174651846)--Thread(Thread[http-nio-8080-exec-1,5,main])--EclipseLink, version: Eclipse Persistence Services - 2.7.1.v20171221-bd47e8f
[EL Fine]: 2018-09-19 07:05:43.765--Thread(Thread[http-nio-8080-exec-1,5,main])--Detected database platform: org.eclipse.persistence.platform.database.DB2Platform
[EL Config]: 2018-09-19 07:05:43.777--ServerSession(174651846)--Connection(393909340)--Thread(Thread[http-nio-8080-exec-1,5,main])--connecting(DatabaseLogin(
    platform=>DatabasePlatform
    user name=> ""
    connector=>JNDIConnector datasource name=>null
))
[EL Config]: 2018-09-19 07:05:43.778--ServerSession(174651846)--Connection(935474207)--Thread(Thread[http-nio-8080-exec-1,5,main])--Connected: jdbc:db2://localhost:50000/SAMPLE
    User: db2inst1
    Database: DB2/LINUXX8664  Version: SQL10055
    Driver: IBM Data Server Driver for JDBC and SQLJ  Version: 4.21.29
[EL Config]: 2018-09-19 07:05:43.778--ServerSession(174651846)--Connection(247275895)--Thread(Thread[http-nio-8080-exec-1,5,main])--connecting(DatabaseLogin(
    platform=>DB2Platform
    user name=> ""
    connector=>JNDIConnector datasource name=>null
))
[EL Config]: 2018-09-19 07:05:43.791--ServerSession(174651846)--Connection(1852461265)--Thread(Thread[http-nio-8080-exec-1,5,main])--Connected: jdbc:db2://localhost:50000/SAMPLE
    User: db2inst1
    Database: DB2/LINUXX8664  Version: SQL10055
    Driver: IBM Data Server Driver for JDBC and SQLJ  Version: 4.21.29
[EL Info]: 2018-09-19 07:05:43.796--ServerSession(174651846)--Thread(Thread[http-nio-8080-exec-1,5,main])--/file:/usr/local/apache-tomee-plume-7.0.5/webapps/MyRestSvc/WEB-INF/classes/_DB2JPA login successful
[EL Warning]: 2018-09-19 07:05:43.799--ServerSession(174651846)--Thread(Thread[http-nio-8080-exec-1,5,main])--Problem while registering MBean: java.lang.NullPointerException
[EL Warning]: 2018-09-19 07:05:43.806--Thread(Thread[http-nio-8080-exec-1,5,main])--The collection of metamodel types is empty. Model classes may not have been found during entity search for Java SE and some Java EE container managed persistence units.  Please verify that your entity classes are referenced in persistence.xml using either <class> elements or a global <exclude-unlisted-classes>false</exclude-unlisted-classes> element
java.lang.IllegalArgumentException: An exception occurred while creating a query in EntityManager: 
Exception Description: Problem compiling [SELECT e FROM Employee e]. 
[14, 22] The abstract schema type 'Employee' is unknown.
    at org.eclipse.persistence.internal.jpa.EntityManagerImpl.createQuery(EntityManagerImpl.java:1743)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:564)
    at org.apache.openejb.persistence.JtaEntityManager.createQuery(JtaEntityManager.java:387)
    at org.apache.openejb.persistence.JtaEntityManager.proxyIfNoTx(JtaEntityManager.java:375)
    at org.apache.openejb.persistence.JtaEntityManager.createQuery(JtaEntityManager.java:329)
    at aaa.bbb.ccc.war.MyRestSvc.get(MyRestSvc.java:40)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:564)
    at org.apache.openejb.core.interceptor.ReflectionInvocationContext$Invocation.invoke(ReflectionInvocationContext.java:205)
    at org.apache.openejb.core.interceptor.ReflectionInvocationContext.proceed(ReflectionInvocationContext.java:186)
    at org.apache.openejb.monitoring.StatsInterceptor.record(StatsInterceptor.java:191)
    at org.apache.openejb.monitoring.StatsInterceptor.invoke(StatsInterceptor.java:102)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:564)
    at org.apache.openejb.core.interceptor.ReflectionInvocationContext$Invocation.invoke(ReflectionInvocationContext.java:205)
    at org.apache.openejb.core.interceptor.ReflectionInvocationContext.proceed(ReflectionInvocationContext.java:186)
    at org.apache.openejb.core.interceptor.InterceptorStack.invoke(InterceptorStack.java:85)
    at org.apache.openejb.core.stateless.StatelessContainer._invoke(StatelessContainer.java:252)
    at org.apache.openejb.core.stateless.StatelessContainer.invoke(StatelessContainer.java:212)
    at org.apache.openejb.util.proxy.ProxyEJB$Handler.invoke(ProxyEJB.java:74)
    at aaa.bbb.ccc.war.MyRestSvc$$LocalBeanProxy.get(aaa/bbb/ccc/war/MyRestSvc.java)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:564)
    at org.apache.openejb.server.cxf.rs.OpenEJBEJBInvoker.performInvocation(OpenEJBEJBInvoker.java:95)
    at org.apache.cxf.service.invoker.AbstractInvoker.invoke(AbstractInvoker.java:96)
    at org.apache.cxf.jaxrs.JAXRSInvoker.invoke(JAXRSInvoker.java:191)
    at org.apache.openejb.server.cxf.rs.OpenEJBEJBInvoker.invoke(OpenEJBEJBInvoker.java:68)
    at org.apache.cxf.jaxrs.JAXRSInvoker.invoke(JAXRSInvoker.java:101)
    at org.apache.openejb.server.cxf.rs.AutoJAXRSInvoker.invoke(AutoJAXRSInvoker.java:64)
    at org.apache.cxf.interceptor.ServiceInvokerInterceptor$1.run(ServiceInvokerInterceptor.java:59)
    at org.apache.cxf.interceptor.ServiceInvokerInterceptor.handleMessage(ServiceInvokerInterceptor.java:96)
    at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308)
    at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:121)
    at org.apache.cxf.transport.http.AbstractHTTPDestination.invoke(AbstractHTTPDestination.java:267)
    at org.apache.openejb.server.cxf.rs.CxfRsHttpListener.doInvoke(CxfRsHttpListener.java:253)
    at org.apache.tomee.webservices.CXFJAXRSFilter.doFilter(CXFJAXRSFilter.java:94)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.apache.openejb.server.httpd.EEFilter.doFilter(EEFilter.java:65)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
    at org.apache.tomee.catalina.OpenEJBValve.invoke(OpenEJBValve.java:44)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:493)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81)
    at org.apache.tomee.catalina.OpenEJBSecurityListener$RequestCapturer.invoke(OpenEJBSecurityListener.java:97)
    at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:650)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:800)
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:800)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1471)
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1135)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.base/java.lang.Thread.run(Thread.java:844)
Caused by: Exception [EclipseLink-0] (Eclipse Persistence Services - 2.7.1.v20171221-bd47e8f): org.eclipse.persistence.exceptions.JPQLException
Exception Description: Problem compiling [SELECT e FROM Employee e]. 
[14, 22] The abstract schema type 'Employee' is unknown.
    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:140)
    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:1741)
    ... 71 more
-
-
-

pom.xml ...

(removed for space - can provide on request)

环境信息...

java 10

EclipseLink (2.7.1)

Dockerized Db2express-c

apache-tomee-7.0.5-plume

1 个答案:

答案 0 :(得分:0)

似乎以某种方式与EclipseLink 2.7.1不兼容。当我更改为使用EclipseLink 2.7.2时,该问题消失了。感谢所有人的意见和建议。

我从这篇文章中得到了一个提示: https://www.eclipse.org/forums/index.php/t/1092642/

其中引用了此错误:
https://bugs.eclipse.org/bugs/show_bug.cgi?id=532882

    <!--does not work...
    <dependency>
        <groupId>org.eclipse.persistence</groupId>
        <artifactId>eclipselink</artifactId>
        <version>2.7.1</version>
    </dependency>  
    -->

    <!-- works as expected...-->     
    <dependency>
        <groupId>org.eclipse.persistence</groupId>
        <artifactId>eclipselink</artifactId>
        <version>2.7.2</version>
    </dependency>