I'll try moving the string array into the client and running each delete in
a separate transaction.  I'll also see if altering the order of deletes
helps the process along.  Some of the relationships entail cascading
deletes, others do not, and not all are bidirectional, so depending on how
sensitive the data source or persistence provider are, I might have to go
carefully through the entities and figure out the proper order for them to
be deleted.  If some rules could be derived about that, we might look into
building tools to assist with this sort of process later on.

I'll let you know how it goes.  I have to admit, working on this is
addictive.

Cheers, and thanks!
--
Alex



On Jan 8, 2008 3:36 PM, Dain Sundstrom <[EMAIL PROTECTED]> wrote:

> 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