Can you try running each delete query in a separate transaction? Something like this in your session bean:

public void clear(String type) {
    Query query = entityManager.createQuery("DELETE FROM " + type)
    query.executeUpdate();
}


and something like this in the test case:

protected void tearDown() {
    String[] types = {...};
    for(String type : types) {
        bean.clear(type);
    }
}

One final thing, if you have foreign key constrained relationships, you will need to make sure the cascade delete settings are correct. For example, if you have an order with many line items and foreign key constraints, you must delete the line items before the order can be deleted. This is normally accomplished with a cascade delete setting on the relationship.

-dain

On Jan 6, 2008, at 2:42 PM, Alexander Saint Croix wrote:

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

Reply via email to