users@glassfish.java.net

Re: EjbTransaction Rollback and PersistenetContext

From: Witold Szczerba <pljosh.mail_at_gmail.com>
Date: Sun, 1 Apr 2007 23:31:57 +0200

2007/4/1, glassfish_at_javadesktop.org <glassfish_at_javadesktop.org>:
> Thanks Josh for the reply.
>
> >Try invoking #method2 using EJB infrastructure and maybe that will help.
> I didnt quite get it, what do you mean by invoking method2 using ejb infrastructure.

...and how does your client-side execute #method1?
When you call stateless session bean, you use either its local or
remote interface. Your bean implementation classes are not the ones
you are actually executing in client code. EJB server wraps invocation
of business methods. In that 'wraping' code, it reads annotations,
checks if there are any xml descriptors, prepares "background" (like,
for example: transaction) and then it invokes your code. When you
prepare #method2 in your bean and then you call that method directly
from within #method1, there is nothing that can tell your EJB server
to do anything with transactions (like starting new one).
Try this: create another session bean, move your #method2 there, then
in your first session bean declare dependency on your secound session
bean and call it, for example:

public class MyService1Bean implements MyService1 {
   /* ....other declarations */
   @EJB MyService2 myService2; //MyService2 is either local or remote interface
   /* .....some other declarations, if any */

  @Transaction(...if you need any non-default transaction settings....)
  public void method1() { //implementing #method1 from MyService1's interface
    /*....some code....*/
    myService2.method2(); //maybe you will have to wrap it in
try/catch(/finally)
    /*....some other code.....*/
}

public class MyService2Bean implements MyService2 {
   /* some declarations, if any */
   @Transaction(....setup transaction here....)
   public void method2() { //implementing #method2 from MyService2's interface
     /* do whatever you want here */
   }
}

Do you see the difference?
In MyService1Bean you are telling EJB server that you will need
MyService2 implementation, so EJB server is preparing special object,
which implements MyService2 interface. That implementation will be
ready for you, when you ask for #method2. When you invoke that method,
you will execute all the special code, that EJB server prepared for
you.

That code will read MyService2Bean annotations, #method2 annotations,
it will check general server configuration, it will do many, many
other things before your code from MyService2Bean executes. That
special, hidden code is known as the implementation of EJB services.
There is all the magic, that can prepare for you new transaction when
you want it (in your case, you new transaction to begine before your
#method2 executes).

None of the above happens when you simply invokes method2() from
within #method1, because nothing is "inspecting" your code
line-by-line trying to determinate what is your code trying to do.