Olá pessoal estou com o seguinte problema, eu tinha um projeto rodando no tomcat 8 perfeitamente e quando estava no tomcat fazia o uso do WELD para o CDI e o Hibernate com sua implementação para o JPA, nesse projeto uso o primefaces 5.3 e lanço mão de um componente do primefaces que é o dataTable e implementei a paginação por banco de dados usando o padrão do primefaces que é extendendo a classe LazyDataModel, até ai tudo funciona perfeitamente pois estou usando para controle de transação uma classe que eu criei e essa transação para ser utilizada é só anotar o método que precisa com @Transaction. O problema acontece quando migrei para o WildFly e com isso passei a usar JTA e DataSources ai a aplicação parou de funcionar devido ao fato que uma das implementações minha desse LazyDataModel é de um model chamado Agencia e esse model possui um relacionamento @ManyToOne com estratégia de carregamento Lazy com o model Banco, e é justamente ai que os erros começaram a acontecer, pois como não estou mais controlando a transação o container que está então à partir daí ele recupera minha entidade Agencia porém no atributo banco já vem dando o seguinte erro que é mostrado na imagem abaixo.
Isso está acontecendo devido ao fato de minha aplicação não mais controlar as transações e sim o container, então nesse contexto em que o container é responsável por isso alguém poderia me ajudar com esse problema mostrando como eu deveria fazer para que o Lazy funcione corretamente igual era no Tomcat 8. Abaixo seguem os arquivos relacionados na descrição do problema.
Agencia.java
`package br.com.r2soft.r2boletos.model;
import br.com.r2soft.r2boletos.util.jpa.converters.LocalDateTimeConverter;
import org.hibernate.envers.Audited;
import javax.persistence.*;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.io.Serializable;
import java.time.LocalDateTime;
@Entity
@Audited
@Table(name = “agencias”)
public class Agencia implements Serializable {
private static final long serialVersionUID = 1L;
private Long id;
private String descricao;
private String numero;
private String digitoVerificador;
private String telefoneContato1;
private String telefoneContato2;
private String pessoaContato;
private Banco banco;
private Boolean lixeira;
private LocalDateTime criado;
private LocalDateTime modificado;
@Id
@SequenceGenerator(name = "agencia_id_seq", sequenceName = "agencia_id_seq", allocationSize = 1, initialValue = 1)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "agencia_id_seq")
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
@Size(max = 40)
@Column(name = "descricao", length = 40, nullable = true)
public String getDescricao() {
return descricao;
}
public void setDescricao(String descricao) {
this.descricao = descricao;
}
@NotNull
@Size(max = 5)
@Column(name = "numero", length = 5, nullable = false)
public String getNumero() {
return numero;
}
public void setNumero(String numero) {
this.numero = numero;
}
@Column(name = "digito_verificador", length = 1, nullable = true)
public String getDigitoVerificador() {
return digitoVerificador;
}
public void setDigitoVerificador(String digitoVerificador) {
this.digitoVerificador = digitoVerificador;
}
@Size(max = 15)
@Column(name = "telefone_contato1", length = 15)
public String getTelefoneContato1() {
return telefoneContato1;
}
public void setTelefoneContato1(String telefoneContato) {
this.telefoneContato1 = telefoneContato;
}
@Size(max = 15)
@Column(name = "telefone_contato2", length = 15)
public String getTelefoneContato2() {
return telefoneContato2;
}
public void setTelefoneContato2(String telefoneContato) {
this.telefoneContato2 = telefoneContato;
}
@Size(max = 40)
@Column(name = "pessoa_contato", length = 40)
public String getPessoaContato() {
return pessoaContato;
}
public void setPessoaContato(String pessoaContato) {
this.pessoaContato = pessoaContato;
}
@NotNull
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "banco_id")
public Banco getBanco() {
return banco;
}
public void setBanco(Banco banco) {
this.banco = banco;
}
@Column(name = "lixeira", nullable = false)
public Boolean getLixeira() {
return lixeira;
}
public void setLixeira(Boolean ativo) {
this.lixeira = ativo;
}
@NotNull
@Convert(converter = LocalDateTimeConverter.class)
@Column(name = "criado", nullable = false)
public LocalDateTime getCriado() {
return criado;
}
public void setCriado(LocalDateTime criado) {
this.criado = criado;
}
@NotNull
@Convert(converter = LocalDateTimeConverter.class)
@Column(name = "modificado", nullable = false)
public LocalDateTime getModificado() {
return modificado;
}
public void setModificado(LocalDateTime modifiado) {
this.modificado = modifiado;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((id == null) ? 0 : id.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Agencia other = (Agencia) obj;
if (id == null) {
if (other.id != null)
return false;
} else if (!id.equals(other.id))
return false;
return true;
}
@Override
public String toString() {
return "Agencia [id=" + id + ", descricao=" + descricao + ", numero=" + numero + ", digitoVerificador="
+ digitoVerificador + "Banco="+ banco + "]";
}
}`
LazyAgenciaModel.java
`package br.com.r2soft.r2boletos.repository.model.lazy;
import br.com.r2soft.r2boletos.model.Agencia;
import br.com.r2soft.r2boletos.repository.AgenciaRepository;
import org.primefaces.model.LazyDataModel;
import org.primefaces.model.SortOrder;
import java.io.Serializable;
import java.util.List;
import java.util.Map;
public class LazyAgenciaModel extends LazyDataModel implements Serializable {
private static final long serialVersionUID = 1L;
private AgenciaRepository agenciaRepository;
public LazyAgenciaModel(AgenciaRepository agenciaRepository) {
this.agenciaRepository = agenciaRepository;
}
@Override
public List<Agencia> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String, Object> filters) {
List<Agencia> agencias = this.agenciaRepository.buscarComPaginacao(first, pageSize);
this.setRowCount(this.agenciaRepository.quantidadeRegistros().intValue());
return agencias;
}
}`
AgenciaBean.java
`package br.com.r2soft.r2boletos.controller.agencia;
import br.com.r2soft.r2boletos.model.Agencia;
import br.com.r2soft.r2boletos.model.Banco;
import br.com.r2soft.r2boletos.model.Conta;
import br.com.r2soft.r2boletos.repository.AgenciaRepository;
import br.com.r2soft.r2boletos.repository.model.lazy.LazyAgenciaModel;
import br.com.r2soft.r2boletos.service.AgenciaService;
import br.com.r2soft.r2boletos.service.BancoService;
import br.com.r2soft.r2boletos.service.ContaService;
import br.com.r2soft.r2boletos.util.MensagemAplicacao;
import br.com.r2soft.r2boletos.util.jsf.FacesUtil;
import javax.faces.view.ViewScoped;
import javax.inject.Inject;
import javax.inject.Named;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.List;
@Named
@ViewScoped
public class AgenciaBean implements Serializable {
private static final long serialVersionUID = 1L;
@Inject
private BancoService bancoService;
@Inject
private AgenciaService agenciaService;
@Inject
private ContaService contaService;
@Inject
private AgenciaRepository agenciaRepository;
private Agencia agencia;
private Agencia agenciaExistente;
private Conta conta;
private String flagEditando;
private String numeroNomeBanco;
private List<Banco> bancos;
private LazyAgenciaModel lazyAgenciaModel;
private List<Agencia> agencias;
public AgenciaBean() {
this.limpar();
}
/*************************************************************
* GETTERS AND SETTERS
**********************************************************/
public Agencia getAgencia() {
return agencia;
}
public void setAgencia(Agencia agencia) {
this.agencia = agencia;
}
public List<Banco> getBancos() {
return this.bancos;
}
public List<Agencia> getAgencias() {
return agencias;
}
public LazyAgenciaModel getLazyAgenciaModel() {
return lazyAgenciaModel;
}
public String getFlagEditando() {
return flagEditando;
}
public void setFlagEditando(String flagEditando) {
this.flagEditando = flagEditando;
}
/*************************************************************
* MÉTODOS DE NEGÓCIO
**********************************************************/
public String salvar() {
if (this.agenciaExistente != null && (this.agencia.getNumero().equals(this.agenciaExistente.getNumero()))) {
if (this.agenciaExistente.getLixeira() != true) {
FacesUtil.adicionarMensagemErro(MensagemAplicacao.getMensagem("agencia_existente_message", this.agencia.getNumero(), this.agencia.getBanco().getNome()));
return "";
}
}
Agencia agenciaSalvo = this.salvarPrivado();
if (agenciaSalvo != null) {
FacesUtil.adicionarMensagemInfo(MensagemAplicacao.getMensagem("r2boletos.salvar.editar.sucesso"));
this.limpar();
return "pretty:listar-agencias";
}
FacesUtil.adicionarMensagemErro(MensagemAplicacao.getMensagem("r2boletos.error"));
return "";
}
public void salvarENovo() {
this.salvar();
}
public String desativar() {
this.agencia.setLixeira(true);
this.agenciaService.desativar(this.agencia);
return this.abandonarTela();
}
public String desativarListagem() {
this.conta = this.verificarSeAgenciaEstaVinculadaAConta();
if (this.conta != null) {
FacesUtil.adicionarMensagemErro(MensagemAplicacao.getMensagem("agencia_erro_excluir"));
return "";
}else {
this.agencia.setLixeira(true);
this.agenciaService.desativar(this.agencia);
this.carregarTodas();
return "";
}
}
/************************************************************
* MÉTODOS UTILITÁRIOS
**********************************************************/
public void limpar() {
this.agencia = new Agencia();
}
public void inicializar() {
if (this.agencia == null) {
this.limpar();
}
if (FacesUtil.isNotPostBack()) {
this.bancos = this.bancoService.listarTodos();
}
}
public void inicializarTabela() {
if (FacesUtil.isNotPostBack()) {
this.carregarTodas();
}
}
private Agencia salvarPrivado() {
return (Agencia) this.agenciaService.salvar(this.agencia);
}
public String abandonarTela() {
return "pretty:listar-agencias";
}
public boolean isEditando() {
return this.agencia.getId() != null;
}
private Conta verificarSeAgenciaEstaVinculadaAConta() {
return this.contaService.buscarPorNumeroAgencia(this.agencia.getNumero(), this.agencia.getBanco().getNumero());
}
public void buscarAgenciaCasoExista() {
this.agenciaExistente = this.agenciaService.buscarPorNumeroAgenciaENumeroBanco(this.agencia.getNumero(), this.agencia.getBanco().getNumero());
if (this.agenciaExistente != null) {
if (this.agenciaExistente.getLixeira() == true) {
this.agencia.setId(this.agenciaExistente.getId());
this.agencia.setLixeira(this.agenciaExistente.getLixeira());
this.agencia.setCriado(LocalDateTime.now());
}
}
}
private void carregarTodas() {
this.lazyAgenciaModel = new LazyAgenciaModel(this.agenciaRepository);
}
}
`
AgenciaService.java
`package br.com.r2soft.r2boletos.service;
import br.com.r2soft.r2boletos.exception.R2BoletosException;
import br.com.r2soft.r2boletos.model.Agencia;
import br.com.r2soft.r2boletos.repository.AgenciaRepository;
import br.com.r2soft.r2boletos.util.MensagemAplicacao;
import br.com.r2soft.r2boletos.util.jsf.FacesUtil;
import javax.enterprise.context.Dependent;
import javax.inject.Inject;
import javax.inject.Named;
import javax.transaction.Transactional;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.List;
<a class="mention" href="/u/named">@Named</a>
@Dependent
@Transactional(rollbackOn = {R2BoletosException.class})
public class AgenciaService implements Serializable {
private static final long serialVersionUID = 1L;
@Inject
private AgenciaRepository agenciaRepository;
public Object salvar(Agencia agencia) {
agencia.setModificado(LocalDateTime.now());
agencia.setLixeira(false);
if (agencia.getId() == null) {
agencia.setCriado(LocalDateTime.now());
}
return this.agenciaRepository.salvar(agencia);
}
public List<Agencia> listarTodos() {
return this.agenciaRepository.carregarTudo();
}
public void desativar(Agencia agencia) {
agencia.setModificado(LocalDateTime.now());
this.agenciaRepository.desativar(agencia);
FacesUtil.adicionarMensagemInfo(MensagemAplicacao.getMensagem("r2boletos.excluir.sucesso"));
}
public Agencia buscarPorNumeroAgenciaENumeroBanco(String numeroAgencia, String numeroBanco) {
Agencia agenciaEncontrada = this.agenciaRepository.buscarPorNumero(numeroAgencia, numeroBanco);
if (agenciaEncontrada != null) {
if (agenciaEncontrada.getLixeira() == true) {
return agenciaEncontrada;
}
FacesUtil.adicionarMensagemErro(MensagemAplicacao.getMensagem("agencia_existente_message", numeroAgencia, agenciaEncontrada.getBanco().getNome()));
return agenciaEncontrada;
}
return null;
}
}
`
GenericRepository.java
`package br.com.r2soft.r2boletos.repository;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import java.io.Serializable;
import java.util.List;
public abstract class GenericRepository implements Serializable {
protected static final long serialVersionUID = 1L;
@PersistenceContext
protected EntityManager em;
private T model;
public void setModel(T model) {
this.model = model;
}
/**
* Salva ou atualiza um banco no banco de dados
*
* @param obj entidade a ser salva no banco de dados
* @return retorna a entidade salva no banco de dados
*/
public T salvar(T obj) {
return this.em.merge(obj);
}
/**
* Apenas desativa uma entidade no banco de dados
* sendo assim ela não aparece mais nas listagens para o cliente
*
* @param objeto a ser desativado
* @return retorna o agencia que foi desativado
*/
public T desativar(T objeto) {
return this.em.merge(objeto);
}
/**
* Recupera uma entidade através ID do mesmo
*
* @param id o ID da entidade a ser buscada
* @return a entidade localizada pelo ID ou null caso não encontre
*/
public T buscarPorId(Long id) {
return this.em.find((Class<T>) this.model.getClass(), id);
}
/**
* Carrega todos os agencias do agencia de dados
*
* @return a lista com todos os itens cadastrados
*/
public List<T> carregarTudo() {
return (List<T>) this.em.createQuery("from " + this.model.getClass().getName() + " a where a.lixeira != true", this.model.getClass()).getResultList();
}
/**
* Método utilizado para saber a quantidade de registros cadastradas no banco de dados
*
* @return a quantidade de registros cadastradas
*/
public Long quantidadeRegistros() {
return this.em.createQuery("select count(a) from " + this.model.getClass().getName() + " a where a.lixeira != true", Long.class).getSingleResult();
}
/**
* Faz a consulta usando paginação
*
* @param first Define à partir de qual linha do banco de dados será retornado os resultados
* @param pageSize Quantidade de resultados por página
* @return A lista de agências já com a paginação aplicada
*/
public List<T> buscarComPaginacao(int first, int pageSize) {
return (List<T>) this.em.createQuery("from " + this.model.getClass().getName() + " a where a.lixeira != true", this.model.getClass())
.setFirstResult(first)
.setMaxResults(pageSize)
.getResultList();
}
public T buscarComPaginacaoPorNome(String nome) {
return (T) this.em.createQuery("from " + this.model.getClass().getName() + " a where a.nome = :nome and a.lixeira != true", this.model.getClass())
.setParameter(":nome", nome)
.getSingleResult();
}
}
`
AgenciaRepository.java
`package br.com.r2soft.r2boletos.repository;
import br.com.r2soft.r2boletos.model.Agencia;
import javax.ejb.Stateless;
import javax.enterprise.context.Dependent;
import javax.inject.Named;
import javax.persistence.NoResultException;
import java.io.Serializable;
@Named
@Dependent
public class AgenciaRepository extends GenericRepository implements Serializable {
private static final long serialVersionUID = 1L;
public AgenciaRepository() {
this.setModel(new Agencia());
}
public Agencia buscarPorNumero(String numeroAgencia, String numeroBanco) {
try {
Agencia agencia = this.em
.createQuery("from Agencia a where a.numero =:numero and a.banco.numero =:banco", Agencia.class)
.setParameter("numero", numeroAgencia)
.setParameter("banco", numeroBanco)
.getSingleResult();
return agencia;
} catch (NoResultException e) {
return null;
}
}
}
`
listar.xhtml
` <ui:composition xmlns=“http://www.w3.org/1999/xhtml”
xmlns:ui=“http://xmlns.jcp.org/jsf/facelets”
xmlns:h=“http://xmlns.jcp.org/jsf/html”
xmlns:f=“http://xmlns.jcp.org/jsf/core”
xmlns:p=“http://primefaces.org/ui”
xmlns:pt=“http://xmlns.jcp.org/jsf/passthrough”
xmlns:jsf=“http://xmlns.jcp.org/jsf”
xmlns:r2soft=“http://xmlns.jcp.org/jsf/composite/composicao”
template="/WEB-INF/template/template.xhtml">
<ui:define name="title">#{msg.agencia_titulo_listar}</ui:define>
<ui:define name="content">
<f:metadata>
<f:viewAction action="#{agenciaBean.inicializarTabela}" />
</f:metadata>
<div class="Container100 Responsive100">
<div class="ContainerIndent">
<div class="ShadowBox whiteback BlueBorderedBox">
<h2 class="BigTopic">#{msg.agencia_subtitulo_listar}</h2>
<div class="EmptyBox20"></div>
<p:messages autoUpdate="true" id="msg" closable="true" />
<h:form id="frm" prependId="false">
<r2soft:botoesListagem outcomeBtnVoltar="pretty:home" outcomeBtnNovo="pretty:adicionar-agencia" />
<div class="EmptyBox20"></div>
<p:dataTable reflow="true" id="tbl-agencias" emptyMessage="#{msg.agencia_tabela_vazia}" rows="5" paginator="true" paginatorAlwaysVisible="false" paginatorPosition="bottom"
value="#{agenciaBean.lazyAgenciaModel}" var="agencia" lazy="true" rowsPerPageTemplate="5, 10, 20, 30, 40, 50, 100">
<p:column styleClass="TexAlCenter" headerText="#{msg.agencia_coluna_banco}" sortBy="#{agencia.banco.nome}">
<h:outputText id="agencia-banco" value="#{agencia.banco.nome}"/>
</p:column>
<p:column styleClass="TexAlCenter" headerText="#{msg.agencia_coluna}" sortBy="#{agencia.numero}">
<h:outputText id="numero-digitoverificador" value="#{agencia.numero} #{not empty agencia.digitoVerificador ? - agencia.digitoVerificador : ''} " />
</p:column>
<p:column headerText="#{msg.agencia_coluna_referencia}" sortBy="#{agencia.descricao}">
<h:outputText id="referencia" value="#{agencia.descricao}" />
</p:column>
<p:column headerText="#{msg.agencia_coluna_contato}" sortBy="#{agencia.pessoaContato}">
<h:outputText id="pessoa-contato" value="#{agencia.pessoaContato}" />
</p:column>
<p:column headerText="#{msg.agencia_coluna_telefone1}" sortBy="#{agencia.telefoneContato1}">
<h:outputText id="telefone" value="#{agencia.telefoneContato1}" />
</p:column>
<p:column headerText="#{msg.agencia_coluna_telefone2}" sortBy="#{agencia.telefoneContato2}">
<h:outputText id="telefone2" value="#{agencia.telefoneContato2}" />
</p:column>
<p:column styleClass="TexAlCenter" headerText="Ações">
<r2soft:botoesTabela outcomeBtnVisualizar="pretty:visualizar-agencia" nomeParametroVisualizar="agencia" valorParametroVisualizar="#{agencia.id}"
outcomeBtnEditar="pretty:editar-agencia" nomeParametroEditar="agencia" valorParametroEditar="#{agencia.id}" mensagemModalDesativar="#{msg.agencia_modal_desativar_message}"
actionBtnExcluir="#{agenciaBean.desativarListagem}" nomeParametroExcluir="#{agencia}" alvoParametroExcluir="#{agenciaBean.agencia}"
atualizarQuaisComponentes="msg tbl-agencias" />
</p:column>
</p:dataTable>
<p:confirmDialog id="confirm-dialog-sair-tela" global="true" showEffect="fade" hideEffect="fade">
<p:commandButton value="#{msg.btn_modal_sim}" type="button" styleClass="ui-confirmdialog-yes" icon="ui-icon-check" />
<p:commandButton value="#{msg.btn_modal_nao}" type="button" styleClass="ui-confirmdialog-no" icon="ui-icon-close" />
</p:confirmDialog>
</h:form>
</div>
</div>
</div>
</ui:define>
</ui:composition>`
