Seguro para guardar a referência para o Feijão da Entidade após a sessão termina?
-
13-09-2020 - |
Pergunta
Este é um muito novato pergunta - por favor, saibam que eu estou ciente de que.
Eu tenho um stateless session bean que precisa de carregar alguns dados uma vez e cache localmente em uma variável estática para uso por todas as instâncias do feijão.Os dados podem ser acessados através de um feijão da entidade.Eu estou querendo saber se é seguro para armazenar em cache a instância da entidade, ou se eu deveria cloná-lo.Além disso, esta entidade também tem sub-entidades.
Chamada de a entidade Foo.Um Foo tem um Bar.No meu bean de sessão, eu gostaria de fazer algo como isto:
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
}
Minhas perguntas:
Esta é uma má idéia?Será que funciona mesmo?
Não há melhor maneira de carregar o Foo dados uma vez que, possivelmente, sem necessidade de que getFoo() método?Fazê-lo estaticamente quando a Sessão classe é carregada parece ser o ideal.
Novo (preciso) código de exemplo, por comentários:
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);
}
}
Solução
Não final em campos estáticos não são permitidos no Stateless Session Beans (SLSB).A partir da especificação EJB3, seção 21.1.2:
Um enterprise bean não deve usar de leitura/gravação campos estáticos.Usando somente leitura campos estáticos é permitido.Portanto, é recomendável que todos os campos estáticos na classe do feijão da empresa ser declarada como final.
Esta regra está lá para garantir a consistência ao distribuir instâncias em várias JVMs.
Então, realmente não era uma boa idéia.A minha sugestão seria a de confiar na cache de segundo nível que o seu APP de maio de provedor de suporte e deixá-lo lidar de forma transparente.
Como uma nota lateral, eu realmente me pergunto por que você tem essa linha no seu bean:
EntityManager em = Container.getInstance().getEntityManager();
Em um ambiente gerenciado, você deve usar um container-managed entidade gestora e obtê-lo injetado em seu SLSB (usando o @PersistenceContext
anotação).