Eclipselink:从持久性数据库写入对象 to/retrieving 对象时出错

Eclipselink: error writing objects to/retrieving objects from persistence database

我最近更换了开发机器,现在从持久性数据库中写入对象 to/retrieving 对象不再有效。当我尝试在我的新机器上调试 webapp 项目时会发生这种情况。 它适用于我的旧笔记本电脑,但不知为何不适用于新笔记本电脑。我还将 webapp 部署到服务器,一切都按预期工作。

我在与数据库交互时收到以下两条错误消息:

正在将对象写入数据库:

SEVERE: Exception sending context initialized event to listener instance of class org.example.webapp.startup.ServletContextClass
java.lang.IllegalArgumentException: Object: org.example.utility.trs.objects.ChangeLog@789a464b is not a known entity type.
    at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.registerNewObjectForPersist(UnitOfWorkImpl.java:4222)
    at org.eclipse.persistence.internal.jpa.EntityManagerImpl.persist(EntityManagerImpl.java:496)
    at org.example.webapp.changelog.dao.ChangeLogDao.addChangeLog(ChangeLogDao.java:42)
    at org.example.webapp.startup.ServletContextClass.initializeChangeLog(ServletContextClass.java:104)
    at org.example.webapp.startup.ServletContextClass.contextInitialized(ServletContextClass.java:59)
    at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4797)
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5221)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1408)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1398)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

写入数据库的代码:

public void addChangeLog(ChangeLog changeLog, EntityManagerFactory emf) {

    String changeLogId = changeLog.getModelResource();

    if(!contentProvider.containsKey(changeLogId)) {

        //create new user
        EntityManager em = emf.createEntityManager();

        em.getTransaction().begin();

        em.persist(changeLog);

        em.getTransaction().commit();
        em.close();

        contentProvider.put(changeLogId, changeLog);
    }

正在从数据库中检索对象:

SEVERE: Exception sending context initialized event to listener instance of class org.example.webapp.startup.ServletContextClass
java.lang.IllegalArgumentException: An exception occurred while creating a query in EntityManager: 
Exception Description: Problem compiling [SELECT c FROM ChangeLog c]. 
[14, 23] The abstract schema type 'ChangeLog' is unknown.
    at org.eclipse.persistence.internal.jpa.EntityManagerImpl.createQuery(EntityManagerImpl.java:1585)
    at org.eclipse.persistence.internal.jpa.EntityManagerImpl.createQuery(EntityManagerImpl.java:1605)
    at org.example.webapp.startup.ServletContextClass.contextInitialized(ServletContextClass.java:59)
    at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4797)
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5221)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1408)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1398)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

从数据库中读取的代码:

List<ChangeLog> changeLogList = em.createQuery("SELECT c FROM ChangeLog c",
                                                ChangeLog.class).getResultList();

下面是 ChangeLog class 的样子:

package org.example.utility.trs.objects;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.NamedQuery;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;

@Entity
@NamedQuery(name="ChangeLog.findAll", query="SELECT c FROM ChangeLog c")
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class ChangeLog  implements Serializable {

    private static final long serialVersionUID = 123L;

    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long changeLogId;
    ...
}

这是 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="webapp-name"  transaction-type="RESOURCE_LOCAL">

        <class>org.example.utility.trs.objects.ChangeLog</class>

        <exclude-unlisted-classes>false</exclude-unlisted-classes>

        <properties>        

            <!-- mysql persistence driver -->
            <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/persistence"/>
            <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
            <property name="javax.persistence.jdbc.username" value="admin"/>
            <property name="javax.persistence.jdbc.password" value="password"/>

            <!-- EclipseLink should create the database schema automatically -->
            <property name="eclipselink.ddl-generation.output-mode" value="database" />
            <property name="javax.persistence.jdbc.user" value="admin"/>
        </properties>
    </persistence-unit>
</persistence>

这是 pom.xml 文件中包含持久性库的部分。如果有任何帮助,我可以 post 整个文件:

<!-- persistence api -->
<dependency>
    <groupId>org.hibernate.javax.persistence</groupId>
    <artifactId>hibernate-jpa-2.0-api</artifactId>
    <version>1.0.1.Final</version>
</dependency>

<dependency>
    <groupId>org.eclipse.persistence</groupId>
    <artifactId>eclipselink</artifactId>
    <version>2.5.0</version>
</dependency>

我可以连接到数据库,并且有一个 table 包含我能够在我的旧开发机器上创建和读取的内容。 因此,我认为问题出在 eclipselink 的配置上,而不是代码中的实际问题。可能是eclipse项目中JPA facet的配置问题。

但是我不知道如何调试这个问题。

另一方面,ChangeLog class 来自另一个项目,该项目存储在我的本地 Maven 存储库中,未在 webapp 项目中定义。所以这可能是个问题。不过,这在我的旧机器上从来都不是问题。

感谢任何帮助

所以经过一些测试,我终于弄清楚出了什么问题。如果其他人遇到这个问题,我把它留在这里。

事实证明,在将代码部署到新的开发机器时,我更改了 pom.xml 文件中的一些依赖版本。所以我用 eclipselink API.

的版本 2.6.4 创建了数据库 table

在新的开发机器上,我将其更改为版本 2.5 并重新编译了破坏从数据库中提取对象的项目。

一旦我改回版本,它又可以工作了。