Olá, na aula de JSF2 estamos fazendo uma anotação na unha para saber como funciona um interceptador e como fazer um.
public class AutorBean implements Serializable{
private static final long serialVersionUID = 1L;
private Autor autor = new Autor();
private Integer autorId;
@Inject
private AutorDAO dao;
//outros métodos etc
@Transacional
public String gravar() {........
}
Temos o AutorDAO injetado pelo CDI, ok. E nele:
public class AutorDAO implements Serializable{
@Inject
EntityManager em;
private DAO<Autor> dao;
@PostConstruct
void init() {
this.dao = new DAO<Autor>(this.em, Autor.class);
}
public void adiciona(Autor t) {
dao.adiciona(t);
}
//etc
Aqui o CDI injeta o EntityManager em e passa-o no construtor da classe DAO genérico e usa esse DAO para os métodos. Agora vamos ao DAO genérico:
public class DAO<T> {
private final Class<T> classe;
private EntityManager em;
public DAO(EntityManager em, Class<T> classe) {
this.em = em;
this.classe = classe;
}
public void adiciona(T t)
em.persist(t);
}
Que recebe o em do construtor e usa para a transação. Porem o método lá no bean estava anotado como @transacional(anotação criada por nós) que aponta para esta classe:
@Transacional
@Interceptor
public class GerenciadorTransacao {
@Inject
EntityManager manager;
@AroundInvoke
public Object executaTx(InvocationContext contexto) throws Exception {
manager.getTransaction().begin();
contexto.proceed();
manager.getTransaction().commit();
Que injeta o EntityManager também. Usa para abrir a transação e continua com o fluxo para o AutorDAO que injeta outro EntityManager cria o DAO generico passando o em este em é o usdo para persistir mas não é fechado saindo do método DAO para comitar em outro Entity. Ou entendi tudo errado?
Resumindo: são injetados dois EntityManager, um pelo AutorDAO e outro pelo interceptador(GerenciadordeTx) um abre a transação e comita mas outro é que realiza? Ficou confuso demais pra mim. A não ser que o CDI reconheça e use o mesmo em que já havia injetado. Obrigado.