Hello,
I'm doing CRUD tests on a collection of integrated entities in a
shared
persistence unit, and am encountering some errors because of crufty
tables
from previous tests. I'm looking for a means of guaranteeing that the
tables for each of my entities is devoid of entries after each test
runs.
The appropriate place to do this would be in the tearDown() method
of the
unit test class.
My environment is OpenEJB (3.0.0 core, latest snapshot), OpenJPA
and an
in-memory HSQLDB. OS X on Java 5.
At the moment, I've implemented a stateless session bean to manage
persistence for me. It's using an injected entity manager to
perform a
series of DELETE statements. Here's how the EM is set up:
@PersistenceContext(unitName = "party-test-unit", type =
PersistenceContextType.TRANSACTION)
private EntityManager entityManager;
I want to stress that I was previously removing entries from the
database by
getting a list of components of a given class, then iteratively
deleting
them. This worked just fine, but was very inefficient and slowed
down the
builds more than was acceptable.
My clear() method defines a String[] of table names, then recursively
creates a Query("DELETE FROM " + table) for each of the bean class
names in
the package I'm testing. Here is the code:
public void clear() {
Set<Query> queries = new HashSet<Query>();
String[] types = {
"Address",
"AssociatedAddress",
"EmailAddress",
"GeographicAddress",
"ISOCountryCode",
"Locale",
"TelecomAddress",
"WebPageAddress",
"AssignedResponsibility",
"Capability",
"PartyRelationship",
"PartyRelationshipType",
"PartyRole",
"PartyRoleType",
"Responsibility",
"Organization",
"OrganizationName",
"Party",
"PartySignature",
"Person",
"PersonName",
"Preference",
"PreferenceOption",
"PreferenceType",
"Property",
"RegisteredIdentifier"};
for(String table : types) {
queries.add(entityManager.createQuery("DELETE FROM " +
table));
}
for(Query query : queries) query.executeUpdate();
}
This method *usually* works. However, sometimes I get *very* strange
nonapplication exceptions that are causing what appear to be
intermittent
test failures. By intermittent I mean a given unit test method
might pass
during one "mvn clean build" process, then fail immediately
afterward during
a second "mvn clean build" process, without any alterations to the
source or
testing code. This happens on some tests, sometimes, and not on
others,
other times, and I can discern no clear pattern. One example of
the error
output is listed at the bottom of this message.
So, what I'm really looking for is a performant way to guarantee
that my
tables are empty between unit tests, so that I'm essentially
starting from a
completely clean environment. I welcome any suggestions, and will
even
entertain non-specification compliant mechanisms provided by
OpenEJB or
OpenJPA to accomplish this.
Dain mentioned that I might completely drop and restart OpenEJB
between
tests. He also mentioned that OpenJPA might have a way to wipe the
database
tables clean for a given persistence unit.
I'm interested in any ideas or feedback about this.
Regards,
--
Alexander R. Saint Croix
As promised, here is the error:
----------------------------------------------------------------------
---------
Test set: org.eremite.corm.party.PersistenceTest
----------------------------------------------------------------------
---------
Tests run: 8, Failures: 0, Errors: 1, Skipped: 0, Time elapsed:
5.749 sec
<<< FAILURE!
testPartySignatureAnnotations
(org.eremite.corm.party.PersistenceTest) Time
elapsed: 0.466 sec <<< ERROR!
javax.ejb.EJBException: The bean encountered a non-application
exception.;
nested exception is:
<openjpa-1.0.1-r420667:592145 fatal general error>
org.apache.openjpa.persistence.PersistenceException: no-saved-fields
at
org.apache.openejb.core.ivm.BaseEjbProxyHandler.convertException(
BaseEjbProxyHandler.java:366)
at org.apache.openejb.core.ivm.BaseEjbProxyHandler.invoke(
BaseEjbProxyHandler.java:323)
at org.apache.openejb.util.proxy.Jdk13InvocationHandler.invoke(
Jdk13InvocationHandler.java:49)
at $Proxy19.clear(Unknown Source)
at
org.eremite.corm.party.PersistenceTest.testPartySignatureAnnotations(
PersistenceTest.java:189)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(
NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(
DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at junit.framework.TestCase.runTest(TestCase.java:164)
at junit.framework.TestCase.runBare(TestCase.java:130)
at junit.framework.TestResult$1.protect(TestResult.java:110)
at junit.framework.TestResult.runProtected(TestResult.java:128)
at junit.framework.TestResult.run(TestResult.java:113)
at junit.framework.TestCase.run(TestCase.java:120)
at junit.framework.TestSuite.runTest(TestSuite.java:228)
at junit.framework.TestSuite.run(TestSuite.java:223)
at org.junit.internal.runners.OldTestClassRunner.run(
OldTestClassRunner.java:35)
at org.apache.maven.surefire.junit4.JUnit4TestSet.execute(
JUnit4TestSet.java:62)
at
org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.executeTest
Set(
AbstractDirectoryTestSuite.java:138)
at
org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.execute(
AbstractDirectoryTestSuite.java:125)
at org.apache.maven.surefire.Surefire.run(Surefire.java:132)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(
NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(
DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at
org.apache.maven.surefire.booter.SurefireBooter.runSuitesInProcess(
SurefireBooter.java:290)
at org.apache.maven.surefire.booter.SurefireBooter.main(
SurefireBooter.java:818)
Caused by: <openjpa-1.0.1-r420667:592145 fatal general error>
org.apache.openjpa.persistence.PersistenceException: no-saved-fields
at org.apache.openjpa.kernel.StateManagerImpl.dirtyCheck(
StateManagerImpl.java:799)
at org.apache.openjpa.kernel.BrokerImpl$ManagedCache.dirtyCheck(
BrokerImpl.java:4620)
at org.apache.openjpa.kernel.BrokerImpl$ManagedCache.access$000(
BrokerImpl.java:4360)
at org.apache.openjpa.kernel.BrokerImpl.hasTransactionalObjects(
BrokerImpl.java:3739)
at org.apache.openjpa.kernel.BrokerImpl.setDirty
(BrokerImpl.java:3856)
at org.apache.openjpa.kernel.StateManagerImpl.setPCState(
StateManagerImpl.java:207)
at org.apache.openjpa.kernel.StateManagerImpl.dirty(
StateManagerImpl.java:1532)
at org.apache.openjpa.kernel.StateManagerImpl.dirty(
StateManagerImpl.java:1471)
at org.apache.openjpa.kernel.StateManagerImpl.dirtyCheck(
StateManagerImpl.java:808)
at org.apache.openjpa.kernel.BrokerImpl$ManagedCache.dirtyCheck(
BrokerImpl.java:4620)
at org.apache.openjpa.kernel.BrokerImpl$ManagedCache.access$000(
BrokerImpl.java:4360)
at org.apache.openjpa.kernel.BrokerImpl.hasTransactionalObjects(
BrokerImpl.java:3739)
at org.apache.openjpa.kernel.BrokerImpl.setDirty
(BrokerImpl.java:3856)
at org.apache.openjpa.kernel.StateManagerImpl.setPCState(
StateManagerImpl.java:205)
at org.apache.openjpa.kernel.StateManagerImpl.delete(
StateManagerImpl.java:1070)
at org.apache.openjpa.kernel.BrokerImpl.delete(BrokerImpl.java:
2518)
at org.apache.openjpa.kernel.SingleFieldManager.delete(
SingleFieldManager.java:387)
at org.apache.openjpa.kernel.SingleFieldManager.delete(
SingleFieldManager.java:373)
at org.apache.openjpa.kernel.SingleFieldManager.delete(
SingleFieldManager.java:330)
at org.apache.openjpa.kernel.SingleFieldManager.delete(
SingleFieldManager.java:284)
at org.apache.openjpa.kernel.StateManagerImpl.cascadeDelete(
StateManagerImpl.java:2817)
at org.apache.openjpa.kernel.BrokerImpl.delete(BrokerImpl.java:
2517)
at org.apache.openjpa.kernel.BrokerImpl.delete(BrokerImpl.java:
2482)
at org.apache.openjpa.kernel.QueryImpl.deleteInMemory
(QueryImpl.java
:1020)
at
org.apache.openjpa.kernel.ExpressionStoreQuery
$DataStoreExecutor.executeDelete
(ExpressionStoreQuery.java:684)
at org.apache.openjpa.kernel.QueryImpl.delete(QueryImpl.java:1008)
at org.apache.openjpa.kernel.QueryImpl.execute(QueryImpl.java:801)
at org.apache.openjpa.kernel.QueryImpl.deleteAll(QueryImpl.java:
866)
at org.apache.openjpa.kernel.QueryImpl.deleteAll(QueryImpl.java:
862)
at org.apache.openjpa.kernel.DelegatingQuery.deleteAll(
DelegatingQuery.java:541)
at org.apache.openjpa.persistence.QueryImpl.executeUpdate
(QueryImpl.java
:314)
at org.eremite.corm.party.BeanManagerImpl.clear
(BeanManagerImpl.java:66)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(
NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(
DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at
org.apache.openejb.core.interceptor.ReflectionInvocationContext
$Invocation.invoke
(ReflectionInvocationContext.java:146)
at
org.apache.openejb.core.interceptor.ReflectionInvocationContext.procee
d(
ReflectionInvocationContext.java:129)
at org.apache.openejb.core.interceptor.InterceptorStack.invoke(
InterceptorStack.java:67)
at org.apache.openejb.core.stateless.StatelessContainer._invoke(
StatelessContainer.java:210)
at org.apache.openejb.core.stateless.StatelessContainer._invoke(
StatelessContainer.java:188)
at org.apache.openejb.core.stateless.StatelessContainer.invoke(
StatelessContainer.java:165)
at
org.apache.openejb.core.ivm.EjbObjectProxyHandler.businessMethod(
EjbObjectProxyHandler.java:217)
at org.apache.openejb.core.ivm.EjbObjectProxyHandler._invoke(
EjbObjectProxyHandler.java:77)
at org.apache.openejb.core.ivm.BaseEjbProxyHandler.invoke(
BaseEjbProxyHandler.java:321)
... 26 more