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.executeTestSet(
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.proceed(
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

Reply via email to