为什么我在尝试 运行 JUnit 测试时收到 "An exception was thrown while searching for persistence archives with ClassLoader" 错误?

Why am I getting an "An exception was thrown while searching for persistence archives with ClassLoader" error when I attempt to run a JUnit test?

我正在尝试 运行 使用 CRUD 数据库函数进行 Junit 测试,但是当我尝试测试该程序时遇到以下错误:

Exception Description: An exception was thrown while searching for persistence archives with ClassLoader

我觉得特别是上面一行是问题所在,但这里是整条消息只是为了确保

To prevent a wall of text


这里是测试代码

package edu.iit.sat.itmd4515.cherna.mp3.root;

import org.junit.Test;
import static org.junit.Assert.*;

public class OnlineVendorTest extends AbstractJPATest{

public OnlineVendorTest() {
}

//implement CRUD for testing
//**********begin create**********
@Test
public void testCreate(){

    tx.begin();
    CarList carList = new CarList();
    carList.setName("2015 Chevy Silverado 1500");
    em.persist(carList);
    tx.commit();
}
//**********end create**********
//**********begin read**********
@Test
public void testRead(){

    Customer c = em.createNamedQuery("Customer.findByName",
    Customer.class).setParameter("firstName","Jesus").getSingleResult();
    assertNotNull(c.getId());

    String query = c.getName();
    System.out.print("#########################" + "\n");
    System.out.print("Customer Name: " + query);
    System.out.print("\n" + "#########################");

    tx.begin();
    tx.commit();
}
//**********end read**********
//**********begin update**********
@Test
public void testUpdate(){

    OnlineVendor ov = em.createNamedQuery("OnlineVendor.findByName",
    OnlineVendor.class).setParameter("name","Cars.com").getSingleResult();
    assertNotNull(ov.getId());

    String oldName = ov.getName();
    String newName = "Cars.net";

    tx.begin();
    ov.setName(oldName);
    tx.commit();
}
//**********end update**********
//**********begin delete**********
@Test
public void testDelete(){

    tx.begin();
    Dealership dealership = new Dealership();
    dealership.setName("CarsGalore");
    em.persist(dealership);
    tx.commit();

    Dealership d = em.createNamedQuery("Dealership.findByName",
    Dealership.class).setParameter("name","CarsGalore").getSingleResult();
    assertNotNull(d.getId());

    tx.begin();
    em.remove(d);
    tx.commit();
}
//**********end delete**********
}

及其扩展的代码

package edu.iit.sat.itmd4515.cherna.mp3.root;

import java.io.Serializable;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;
import javax.persistence.TypedQuery;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;

public abstract class AbstractJPATest{

private static EntityManagerFactory emf;
protected EntityManager em;
protected EntityTransaction tx;

@BeforeClass
public static void setUpClass(){
    emf = Persistence.createEntityManagerFactory("chernaPU");
}

@AfterClass
public static void tearDownClass(){
    emf.close();
}

@Before
public void setUp(){
    em = emf.createEntityManager();
    tx = em.getTransaction();
    makeTestData();
}

private void makeTestData(){
    //put initial names in tables
    tx.begin();
    OnlineVendor onlineVendor = new OnlineVendor();
    onlineVendor.setName("Cars.com");
    CarList carList = new CarList();
    carList.setName("2014 Chevy Silverado 1500");
    CustRecord custRecord = new CustRecord();
    Dealership dealership = new Dealership();
    dealership.setName("WeSellCars");
    Car car = new Car();
    car.setYear(2008);
    car.setMake("Pontiac");
    car.setModel("Grand Prix");
    custRecord.setName("P. Sherman 42 Wallaby Way, Sydney");
    Customer customer = new Customer();
    customer.setFirstName("Jesus");
    customer.setLastName("Munoz");
    em.persist(carList);
    em.persist(custRecord);
    em.persist(dealership);
    em.persist(onlineVendor);
    em.persist(car);
    em.persist(customer);
    tx.commit();
}

@After
public void tearDown(){
    removeTestData();
    em.close();
}

private void removeTestData(){
    //dynamic query
    //delete OnlineVendor
    TypedQuery<OnlineVendor> qov = em.createQuery("select ov from OnlineVendor ov where ov.name = ?1",OnlineVendor.class);
    qov.setParameter(1,"Cars.com");
    OnlineVendor ov = qov.getSingleResult();
    //named query (seems more efficient)
    //delete CustRecord
    CustRecord cr = em.createNamedQuery("CustRecord.findByName",
    CustRecord.class).setParameter("name","P. Sherman 42 Wallaby Way, Sydney").getSingleResult();
    //delete Dealership
    Dealership d = em.createNamedQuery("Dealership.findByName",
    Dealership.class).setParameter("name","WeSellCars").getSingleResult();
    //delete Customer
    Customer c = em.createNamedQuery("Customer.findByFirstName",
    Customer.class).setParameter("firstName","Jesus").getSingleResult();
    //delete CarList
    CarList cl = em.createNamedQuery("CarList.findByName",
    CarList.class).setParameter("name","2014 Chevy Silverado 1500").getSingleResult();

    tx.begin();
    em.remove(ov);
    em.remove(cr);
    em.remove(cl);
    em.remove(d);
    em.remove(c);
    tx.commit();
}
}

这里是 pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>edu.iit.sat.itmd4515.cherna.mp3</groupId>
<artifactId>cherna-mp3</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.7</maven.compiler.source>
    <maven.compiler.target>1.7</maven.compiler.target>
</properties>
<dependencies>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.eclipse.persistence</groupId>
        <artifactId>eclipselink</artifactId>
        <version>2.5.2</version>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.34</version>
    </dependency>
    <dependency>
        <groupId>org.eclipse.persistence</groupId>
        <artifactId>org.eclipse.persistence.jpa.modelgen.processor</artifactId>
        <version>2.5.2</version>
        <scope>provided</scope>
    </dependency>
</dependencies>

这里是 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="chernaPU" transaction-type="RESOURCE_LOCAL">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<class>edu.iit.sat.itmd4515.cherna.mp3.root.Car</class>
<class>edu.iit.sat.itmd4515.cherna.mp3.root.CarList</class>
<class>edu.iit.sat.itmd4515.cherna.mp3.root.CustRecord</class>
<class>edu.iit.sat.itmd4515.cherna.mp3.root.Customer</class>
<class>edu.iit.sat.itmd4515.cherna.mp3.root.Dealership</class>
<class>edu.iit.sat.itmd4515.cherna.mp3.root.OnlineVendor</class>
<properties>
  <property name="javax.persistence.schema-generation.scripts.action" value="drop-and-create"/>
  <property name="javax.persistence.schema-generation.scripts.create-target" value="create.sql"/>
  <property name="javax.persistence.schema-generation.scripts.drop-target" value="drop.sql"/>
  <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/itmd4515?zeroDateTimeBehavior=convertToNull"/>
  <property name="javax.persistence.jdbc.user" value="itmd4515"/>
  <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
  <property name="javax.persistence.jdbc.password" value="itmd4515"/>
  <property name="javax.persistence.schema-generation.database.action" value="drop-and-create"/>
</properties>

这是身份class

package edu.iit.sat.itmd4515.cherna.mp3.root;

import javax.persistence.MappedSuperclass;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

@MappedSuperclass
public class Identity extends EntityTemplate{

@Temporal(TemporalType.DATE)
private String lastName;
private String firstName;

/**
 * Get the value of lastName
 *
 * @return the value of lastName
 */
public String getLastName() {
    return lastName;
}

/**
 * Set the value of lastName
 *
 * @param lastName new value of lastName
 */
public void setLastName(String lastName) {
    this.lastName = lastName;
}

/**
 * Get the value of firstName
 *
 * @return the value of firstName
 */
public String getFirstName() {
    return firstName;
}

/**
 * Set the value of firstName
 *
 * @param firstName new value of firstName
 */
public void setFirstName(String firstName) {
    this.firstName = firstName;
}


}

及其扩展的class

package edu.iit.sat.itmd4515.cherna.mp3.root;

import java.util.Date;
import java.util.GregorianCalendar;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.MappedSuperclass;
import javax.persistence.PrePersist;
import javax.persistence.PreUpdate;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;


//This sets up Id code for other entities to extend
@MappedSuperclass
public class EntityTemplate {

@Id
@GeneratedValue (strategy = GenerationType.IDENTITY)
private Long id;
@Temporal(TemporalType.TIMESTAMP)
private Date lastUpdated;

@PreUpdate
@PrePersist
private void setLastUpdated(){
    lastUpdated = GregorianCalendar.getInstance().getTime();
}

public Long getId(){
    return id;
}

/**
 * Get the value of lastUpdated
 *
 * @return the value of lastUpdated
 */
public Date getLastUpdated() {
    return lastUpdated;
}

}

现在是实际问题:昨天测试(所有测试)顺利通过,但今天每当我尝试 运行 测试时,我开始收到规定的错误消息。我调查了一下,发现它可能与 jar、Eclipselink 以及 persistence.xml 的加载方式有关,但即便如此我也找不到解决方案。我找到了一种方法,解释说修改 manifest.mf 可以解决问题,所以我试了一下,但没有用。我还在 Eclipse 中看到了一些解决问题的方法,但我使用的是 Netbeans。我知道,至少,问题出在所提供代码的某个地方,因为在注释掉 CRUD 方法后我没有收到任何错误(但这违背了目的。)

tl;dr 如何摆脱错误消息?

其他信息:

这是 Netbeans 中的 Maven java 项目。

此项目已链接到 Bitbucket 存储库。



如果我遗漏了任何重要信息,请告诉我

根据您的日志,根本原因似乎是这个

Internal Exception: Exception [EclipseLink-7165] (Eclipse Persistence Services - 2.5.2.v20140319-9ad6abd): org.eclipse.persistence.exceptions.ValidationException
Exception Description: The type [class java.lang.String] for the attribute [lastName] on the entity class [class edu.iit.sat.itmd4515.cherna.mp3.root.Identity] is not a valid type for a temporal mapping. The attribute must be defined as java.util.Date or java.util.Calendar.

问题出在这段代码

@MappedSuperclass
public class Identity extends EntityTemplate{

@Temporal(TemporalType.DATE) <--- are you sure this is right?
private String lastName; <---- if yes, then this field's type should be date or timestamp