Observando o acesso ao banco de dados utilizando JSF e JPA percebi que ele faz muitos acessos seguidos ao banco de dados quando era para fazer apenas 1. Gostaria de saber se realmente é desse jeito. Para ilustrar vou exemplificar com um CRUD de Marcas.
@Entity
public class Marca implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String nome;
@OneToMany(mappedBy = "marca")
private List<Produto> produtos;
Agora segue o codigo do dao:
@Transactional(readOnly=true, propagation= Propagation.REQUIRED)
public class DaoGenericoImpl<T, ID extends Serializable> implements DaoGenerico<T, ID> {
private final Class<T> oClass;
@Autowired
private JpaTemplate jt;
@Override
public List<T> listar() {
System.out.println("chamada ao metodo listar()");
return jt.find("select obj from " + oClass.getSimpleName() + " obj");;
}
Agora o metodo do managedBean
@Component
@RequestScoped
@ManagedBean(name = "marcaController")
public class MarcaController {
@Autowired
private MarcaDao marcaDao;
private Marca marca;
private DataModel marcas;
public DataModel getMarcas() {
marcas = new ListDataModel(marcaDao.listar());
return marcas;
}
Agora a pagina que lista as marcas cadastradas no banco de dados.
<h:form>
<h:dataTable value="#{marcaController.marcas}" var="marca" rendered="#{marcaController.marcas.rowCount>0}">
<h:column>
<f:facet name="header">
CODIGO
</f:facet>
<h:outputLabel value="#{marca.id}"/>
</h:column>
<h:column>
<f:facet name="header">
NOME
</f:facet>
<h:outputLabel value="#{marca.nome}"/>
</h:column>
<h:column>
<f:facet name="header">
OPCOES
</f:facet>
<h:commandButton value="Consultar" action="#{marcaController.consultar()}"/>
<h:commandButton value="Alterar" action="#{marcaController.editar()}"/>
<h:commandButton value="Excluir" action="#{marcaController.excluir()}"/>
</h:column>
</h:dataTable>
Pelo ciclo de vida do JSF eu so chamo o metodo getMarcas() para montar a tabela 1 vez quando acesso a pagina e este por sua vez chama o metodo listar() do Dao 1 vez tambem. Acontece que quando eu rodo a aplicacao o print que coloquei no metodo aparece 10 vezes. Tanto faz o bean ser de sessao ou request. Para tirar a nêga, eu liguei o log global do mysql e la aparece o select 10 vezes tambem. Alguem sabe dizer se esse é o comportamento padrao ou um problema de configuracao?
Log do mysql:
10 Query SET autocommit=1
10 Query SET autocommit=0
10 Query select marca0_.ID as ID0_, marca0_.NOME as NOME0_ from papangudb.MARCA marca0_
10 Query commit
10 Query SET autocommit=1
10 Query SET autocommit=0
10 Query select marca0_.ID as ID0_, marca0_.NOME as NOME0_ from papangudb.MARCA marca0_
10 Query commit
10 Query SET autocommit=1
10 Query SET autocommit=0
10 Query select marca0_.ID as ID0_, marca0_.NOME as NOME0_ from papangudb.MARCA marca0_
10 Query commit
10 Query SET autocommit=1
10 Query SET autocommit=0
10 Query select marca0_.ID as ID0_, marca0_.NOME as NOME0_ from papangudb.MARCA marca0_
10 Query commit
10 Query SET autocommit=1
10 Query SET autocommit=0
10 Query select marca0_.ID as ID0_, marca0_.NOME as NOME0_ from papangudb.MARCA marca0_
10 Query commit
10 Query SET autocommit=1
10 Query SET autocommit=0
10 Query select marca0_.ID as ID0_, marca0_.NOME as NOME0_ from papangudb.MARCA marca0_
10 Query commit
10 Query SET autocommit=1
10 Query SET autocommit=0
10 Query select marca0_.ID as ID0_, marca0_.NOME as NOME0_ from papangudb.MARCA marca0_
10 Query commit
10 Query SET autocommit=1
10 Query SET autocommit=0
10 Query select marca0_.ID as ID0_, marca0_.NOME as NOME0_ from papangudb.MARCA marca0_
10 Query commit
10 Query SET autocommit=1
10 Query SET autocommit=0
10 Query select marca0_.ID as ID0_, marca0_.NOME as NOME0_ from papangudb.MARCA marca0_
10 Query commit
10 Query SET autocommit=1