Eclipselink:将对象写入/检索持久性数据库中的对象时出错

时间:2017-08-22 08:59:54

标签: java eclipse jpa eclipselink persistence.xml

我最近切换了开发机器,现在将对象写入/从持久性数据库中检索对象不再起作用了。当我尝试在我的新机器上调试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类的外观:

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文件的一部分。如果有任何帮助,我可以发布整个文件:

<!-- 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>

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

但我不知道如何调试此问题。

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

感谢任何帮助

1 个答案:

答案 0 :(得分:0)

经过一些测试后,我终于弄明白出了什么问题。如果有其他人遇到这个问题,我就把它留在这里。

事实证明,在将代码部署到新开发机器时,我更改了pom.xml文件中的一些依赖版本。因此,我使用2.6.4 API的版本eclipselink创建了数据库表。

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

一旦我更改了版本,它再次起作用。