OK, so pardon my lack of clue here.  This is kind of a minor conundrum, but 
maybe someone knows the answer off the top of their head.

I am writing a base class for versioned objects.  These versioned objects can 
make (dynamically) immutable copies of themselves.  I call these copies 
"snapshots".  

To ensure that my code doesn't modify the supposed-to-be-immutable snapshots, I 
have a @PreUpdate method in the base class which checks to see if the object is 
a snapshot (which is true iff its "replicatedChangeset" field is non-null).  If 
it is, the @PreUpdate throws a SnapshotModifiedException.
@Entity
  | @Inheritance(strategy=InheritanceType.JOINED)
  | public abstract class RepObject {
  | ...
  |    private Changeset replicatedChangeset;
  | ...
  |    @PreUpdate
  |    private void checkUpdate () {
  |       log.debug("Calling checkUpdate on " + this + "...");
  |       if (replicatedChangeset != null) {
  |          throw new SnapshotModifiedException(this);
  |       }
  |    }
  | ...
  | }
SnapshotModifiedException:
@ApplicationException(rollback=true)
  | public class SnapshotModifiedException
  |     extends RuntimeException
  | {
  |     RepObject snapshot;
  | 
  |     public SnapshotModifiedException(RepObject snapshot) {
  |         this.snapshot = snapshot;
  |         assert snapshot.getReplicatedChangeset() != null;
  |     }
  | ...
  | }

This all works fine, actually.

So now, naturally enough, I want to write a SeamTest that tries to modify a 
snapshot object, and then fails if the modification is successful, and passes 
if the modification blows up as expected.  Here's my attempt:

         @Override
  |          protected void updateModelValues()
  |          {
  |             entityManager = (EntityManager) 
Component.getInstance("entityManager", true);
  |             changesetLog = (ChangesetLog) 
Contexts.getApplicationContext().get("changesetLog");
  |          }
  | 
  |          @Override
  |          protected void invokeApplication()
  |          {
  |             // ... get a list of snapshot objects in the List 
priorBlogPosts ...
  |             try {
  |                BlogPost prior1 = priorBlogPosts.get(0);
  |                prior1.setTitle("changedTitle");  // shouldn't change a 
snapshot!
  | 
  |                // trigger the @PreUpdate check
  |                entityManager.flush();
  | 
  |                assert false; // plan to die if we get this far; should get 
exception from the flush
  |             } catch (RuntimeException e) {
  |                log.info("Got expected exception from attempted snapshot 
update", e);
  | 
  |                // rethrow e... since it's marked as 
@ApplicationException(rollback=true), should roll back peacefully?!
  |                throw e;
  |             }
  |          }

Now, this obviously doesn't work, because I rethrow the exception, so the test 
dies.  (Note that the exception is not a SnapshotModifiedException, it's an 
InvocationTargetException wrapping a SnapshotModifiedException.  Oh well.)

But what should I do instead?  If I swallow the exception, the test will still 
die, because it will try to flush again and fail.  I think I want to do 
setRollbackOnly.  But I don't actually know how to *do* setRollbackOnly from 
inside a SeamTest.  The only syntax I see for it is (from the dvd example):
@Resource
  | SessionContext ctx; 
  | ...
  | ctx.setRollbackOnly();

But this can't be done from a SeamTest.  If I just change my test to:
         @Resource
  |          SessionContext ctx;
  | ...
  |             } catch (RuntimeException e) {
  |                log.info("Got expected exception from attempted snapshot 
update", e);
  | 
  |                ctx.setRollbackOnly();
  |             }
Then I get a NullPointerException because SeamTests don't seem to support 
@Resource injection, so ctx is null.  So how do I get a hold of a 
javax.ejb.SessionContext in my SeamTest to make it roll back peacefully?

Basically I'm between a rock and a hard place:
1) If I swallow the exception, then the test blows up when it tries to commit, 
because it flushes again and hits the exception again.
2) If I rethrow the exception, then the test blows up because an exception 
thrown out a test causes a test failure.
3) I can't do "ctx.setRollbackOnly();" in my catch clause because I don't know 
how to inject or otherwise obtain a javax.ejb.SessionContext in my test.

Obviously I could just punt on this whole test, but this is really important 
functionality in my little framework and I want a test for it :-)

Clues, anyone?  There's probably some dead simple way to get the SessionContext 
from inside a SeamTest... I just can't imagine what it is!

Thanks!
Cheers,
Rob

View the original post : 
http://www.jboss.com/index.html?module=bb&op=viewtopic&p=3956875#3956875

Reply to the post : 
http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=3956875
_______________________________________________
jboss-user mailing list
[email protected]
https://lists.jboss.org/mailman/listinfo/jboss-user

Reply via email to