Bonjour, je me pose beaucoup de questions autour du terme business methods.
En effet lors de mes dernières expériences, je constate plusieurs choses qui me laissent perplexe :

Soit le code suivant simplifié...
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
@Stateless
@LocalBean
public AClass {
   @EJB
   BClass bclass;
 
   @TransactionAttribute(NOT_SUPPORTED)
   public void aMethod() {
       bMethod();
       cMethod();
       bClass.dMethod();
       bClass.eMethod();
   }
   @TransactionAttribute(REQUIRED_NEW)
   public void bMethod() {
   }
   @Asynchronous
   public void cMethod() {
   }
}
 
public BClass {
   @TransactionAttribute(REQUIRED_NEW)
   public void dMethod() {
   }
   @Asynchronous
   public void eMethod() {
   }
}
Je constate la chose suivante :
aMethod comme prévu n'est pas dans une transaction : NOT_SUPPORTED.
bMethod N'est PAS dans une transaction malgré REQUIRED_NEW
cMethod N'est PAS Asynchronous malgré Asynchronous
dMethod est dans une nouvelle transaction quoi qu'il arrive
eMethod est asynchronous

Donc si je comprends bien mes lectures et mes constatations : bMethod et cMethod ne sont pas des business method dans ce cas, mais pourrait l’être dans le cas d'un autre appel, les autres oui car elle sont appelées par extérieure de l'EJB.
Je constate aussi la même chose quand à l'application des Interceptors.

soit un interceptor :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
public AInterceptor {
  @AroundInvoke
  public Object process(InvocationContext ic)  throws Exception {
     return ic.proccess();
  }
}
puis sur la class :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
@Interceptors(AInterceptor.class)  
    public class AClass {  ...}
Seule la methode aMethod (appelé de l'exterieur) sera "décoré" par l'interceptor.

Déjà à ce stade, je trouve cela bien dommage et surtout pas très clair.

Maintenant un cas pratique :

Soit un ejb gérant la persistance d'une Entity
celui ci permet de persister une entité ou plusieurs entités à la fois comme suit, mais je veux que quoi qui l'arrive chaque persistance soit individuelle. Mais les transactions gérer par le container toujours.

Naïvement :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
...
@TransactionAttribute(REQUIRED_NEW)
public void persistOk(MonEntity o) throws NokException(){
// code de persistence metant en oeuvre plusieurs persitence d'objets
... throw new NokException(); // ou pas
}
 
@TransactionAttribute(REQUIRED_NEW)
public void persistNok(MonEntity o) {}
 
@TransactionAttribute(REQUIRED_NEW)
public void persistList(Collection<MonEntity> list {
   for(MonEntity  o : list) {
      try {
        persistOk(o); 
      } catch(NokException ne) {
        persistNok(o);
      }
}
...
on pourrait imaginer que si j'appelle persistList, chaque persistOk et persistNok soit dans leur propre transaction. Il n'en ai rien. seule persistList crée une nouvelle transaction.
Le code précédent ne marche donc pas.
En revanche si vous déplacer dans un autre EJB les methodes persistOk et persistNok. tout rentre dans l'ordre.

Quelque chose m’échappe ? Je réalise une grosse appli, et mes EJBs se compte par dizaines. et certains ont parfois plusieurs dizaines de méthode. Si mes constatation sont justes, il va falloir revoir pas mal de truc.
Mes EJBs on plutôt tendances à gérer un coté fonctionnel. un EJB pour s'occuper des Users, un, EJB pour les Groups etc... N'est ce pas comme cela qu'il faut faire ???
J'avoue être très perplexe. J'ai plutôt tendance à essayer de laisser le container gérer le plus de chose. Je sais bien que l'on peut gérer les Transaction en mode BEAN, mais je pense que normalement cela devrait être à utiliser qu'en cas d'impasse avec le container.
Je lis tout ce qui me tombe sur la main, mais les exemples sont souvent très simplistes.
Quelqu'un à t'il quelques tuyaux, ouvrages, tutos qui explique les transactions et tout ce qui va autour vraiment en détails ?

Cordialement