为什么我在尝试 运行 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
我觉得特别是上面一行是问题所在,但这里是整条消息只是为了确保
这里是测试代码
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
我正在尝试 运行 使用 CRUD 数据库函数进行 Junit 测试,但是当我尝试测试该程序时遇到以下错误:
Exception Description: An exception was thrown while searching for persistence archives with ClassLoader
我觉得特别是上面一行是问题所在,但这里是整条消息只是为了确保
这里是测试代码
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