2010-07-09 18 views
1

Il s'agit d'une question de débutant - s'il vous plaît sais que je suis conscient de cela.Coffre-fort pour stocker la référence à Entity Bean après la fin de la session?

J'ai un bean de session sans état qui a besoin de charger une partie de données et de le mettre en cache localement dans une variable statique pour une utilisation par toutes les instances de ce bean. Les données peuvent être accessibles via un bean entité. Je me demande s'il est sûr de mettre en cache l'instance d'entité, ou si je devrais le cloner. En outre, cette entité a également des sous-entités.

Appelle l'entité Foo. Un Foo a un bar. Dans mon bean session, je voudrais faire quelque chose comme ceci:

private static final FOO_ID = 123L; 

private static Foo foo; 

private static Foo getFoo(EntityManager em) { 
    if (foo != null) 
     return foo; 
    return foo = (Foo) em.find(Foo.class, FOO_ID); 
} 

public void someBusinessMethod() { 
    EntityManager em = Container.getInstance().getEntityManager(); 
    Foo foo = getFoo(em); 
    Bar bar = foo.getBar(); 
    // do some stuff with foo and bar 
} 

Mes questions:

  1. Est-ce une mauvaise idée? Est-ce que ça va marcher?

  2. Existe-t-il un meilleur moyen de charger les données Foo une seule fois, peut-être sans avoir besoin de cette méthode getFoo()? Le faire de façon statique lorsque la classe Session est chargée semblerait idéal.

Nouveau code d'échantillon (précis), par commentaires:

public class Foo { // entity 
    private Long id; 
    private String name; 
    // getters and setters 
} 

public class Bar { // entity 
    private Long id; 
    private String name; 
    // getters and setters 
} 

public class FooHelper implements Helper { 
    private static final long FOO_ID = 123L; 
    private Foo foo; 
    public FooHelper() { 
     // use FOO_ID to look up a Foo & cache it locally 
    } 
    @Override 
    public void addBar(EntityManager em) { 
     Bar bar = new Bar(); 
     bar.setName(foo.getName()); 
     em.persist(bar); 
    } 

public class StatelesSessionBean { 
    private static final Helper helper = new FooHelper(); 
    public void someBusinessMethod() { 
     @PersistenceContext 
     EntityManager em; 
     helper.addBar(em); 
    } 
} 

Répondre

2

champs statiques non finales ne sont pas autorisés dans Stateless Session Beans (SLSB). À partir de la spécification EJB3, section 21.1.2:

Un bean enterprise ne doit pas utiliser des champs statiques en lecture/écriture. L'utilisation de champs statiques en lecture seule est autorisée. Par conséquent, il est recommandé que tous les champs statiques de la classe Bean Enterprise soient déclarés comme définitifs.

Cette règle est là pour assurer la cohérence lors de la distribution d'instances sur plusieurs JVM.

Donc pas vraiment une bonne idée. Ma suggestion serait de s'appuyer sur le cache de second niveau que votre fournisseur JPA peut supporter et de le laisser gérer cela de manière transparente.

Comme une note de côté, je vraiment se demander pourquoi vous avez cette ligne dans votre haricot:

EntityManager em = Container.getInstance().getEntityManager(); 

Dans un environnement géré, vous devez utiliser un gestionnaire d'entités gérée par conteneur et obtenir injecté dans votre SLSB (en utilisant l'annotation @PersistenceContext).

+0

Rétrospectivement, mon code d'exemple ne reflète pas exactement ce que j'essaie de faire. Va ajouter un nouvel échantillon à la publication originale. – jph

+0

Fondamentalement ma question est comment accomplir la partie commentée du constructeur de FooHelper. – jph

+0

@ user190758 Ma réponse s'applique toujours: utilisez la fonctionnalité de cache de second niveau de votre fournisseur JPA pour mettre en cache l'entité 'Foo' * de manière transparente * pour vous. C'est le chemin à parcourir. –