users@glassfish.java.net

Re: EjbTransaction Rollback and PersistenetContext

From: Witold Szczerba <pljosh.mail_at_gmail.com>
Date: Mon, 2 Apr 2007 03:12:18 +0200

I am not sure, but I think you can invoke #method2 from within
#method1 when they are both in the same session bean using
SessionContext.
So, instead of splitting your session bean into two session beans and
moving #method2, you can try this instead:

public class MySessionBean implements MySession {
 ....
 @Reource SessionContext ctx;
 ....
 public void method1() {


    ......some code.....
    for(SomeObject obj : someObjectList)
    {
    ..............some code....
    //call method2
    ctx.getBusinessObject(MySession.clsss).method2(obj);
    .........some code......
    }
 }
}

where "MySession" is the >interface< you are implementing in your session bean.
That should work exactly the same way as in my previous post, but
there is no need to create another session bean. To avoid some
problems: remember - never use any instance fields other than the ones
managed by EJB container to store some data in @Stateless session
beans. You must be aware of that, when invoking any method of
stateless session bean - you never know which instance of bean will be
used (and you don't know how many of them exists). That means, your
method2 might be executed on different object than method1. Also,
remember that when your method1 throws exception, EJB will rollback
any changes made in persistent storage, or any other JTA aware
resource.
Hope that helps.


2007/4/1, Witold Szczerba <pljosh.mail_at_gmail.com>:
> 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.
>