Sicuro per conservare il riferimento a Entity Bean dopo la fine della sessione?
-
13-09-2020 - |
Domanda
Questa è una bella domanda principiante- per favore sappi che ne sono consapevole.
Ho un fagiolo di sessione apolidi che ha bisogno di caricare alcuni dati una volta e la cache localmente in una variabile statica per l'uso da parte di tutte le istanze di quel bean.I dati sono accessibili tramite un fagiolo di entità.Mi sto chiedendo se è sicuro cache l'istanza dell'entità, o se dovrei clonarlo.Inoltre, questa entità ha anche sub-entità.
Chiama l'entità foo.Un foo ha un bar.Nel mio fagiolo di sessione, mi piacerebbe fare qualcosa del genere:
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
}
.
Le mie domande:
- .
-
è una cattiva idea?Lavorerà anche?
-
C'è un modo migliore per caricare una volta i dati Foo, possibilmente senza necessità di quel metodo GetFoo ()?Farlo staticamente quando la classe di sessione è caricata sembrerebbe essere ideale.
Nuovo codice di esempio (accurato), per commenti:
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);
}
}
.Soluzione
I campi statici non finali non sono consentiti nei bean di sessioni apolidi (SLSB).Dalla specifica EJB3, sezione 21.1.2:
.Un Bean Enterprise non deve utilizzare campi statici di lettura / scrittura.L'uso di campi statici di sola lettura è consentito.Pertanto, si consiglia di dichiarare tutti i campi statici nella classe Bean Enterprise come definitivo.
Questa regola è lì per garantire la coerenza quando si distribuiscono le istanze su più JVMS.
Quindi non è davvero una buona idea.Il mio suggerimento sarebbe quello di fare affidamento sulla cache del secondo livello che il tuo provider JPA può supportare e lasciarlo gestire in modo trasparente.
Come nota laterale, io davvero chiedi perché hai questa linea nel tuo fagiolo:
EntityManager em = Container.getInstance().getEntityManager();
.
In un ambiente gestito, è necessario utilizzare un gestore di Entity container-Managed e ottenerlo iniettato nel proprio SLSB (utilizzando l'annotazione @PersistenceContext
).