2
respostas

Duvida conceitual sobre consultas com query nativa utilizando spring data

Preciso executar um sql nativo em um banco de dados. Este sql ja utiliza algumas funcoes criadas no banco de dados especificas para o negocio. Neste caso utilizando um sql nativo, como deveria criar a classe de repositorio que ira acessar o banco de dados, uma vez que a mesma nao possui nenhuma tabela existente vinculada? Nao faz sentido extender de JpaRepository<TD,ID> uma vez que nao tenho esta classe de entidade no banco. A classe de modelo SaldoDeContaContabil ira encapsular estes dados.

Classe de modelo:

 public class SaldoDeContaContabil {
    private ContaContabil contaContabil;
    private double saldoInicial;
    private NaturezaContabil naturezaDoSaldoInicial;
    private double debitos;
    private double creditos;
    private double saldoFinal;
    private NaturezaContabil naturezaDoSaldoFinal;
    private int sequenciaDeImpressao;

    public SaldoDeContaContabil(ContaContabil contaContabil, double saldoInicial,
            NaturezaContabil naturezaDoSaldoInicial, double debitos, double creditos, double saldoFinal,
            NaturezaContabil naturezaDoSaldoFinal, int sequenciaDeImpressao) {
        this.contaContabil = contaContabil;
        this.saldoInicial = saldoInicial;
        this.naturezaDoSaldoInicial = naturezaDoSaldoInicial;
        this.debitos = debitos;
        this.creditos = creditos;
        this.saldoFinal = saldoFinal;
        this.naturezaDoSaldoFinal = naturezaDoSaldoFinal;
        this.sequenciaDeImpressao = sequenciaDeImpressao;
    }

    // getters omitidos...
}

Classe de acesso ao banco de dados

package br.com.xpto.erp.model.repository;

import java.time.LocalDate;
import java.util.List;

import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

import br.com.atac.erp.model.entity.SaldoDeContaContabil;

public interface SaldoDeContaContabilRepository {

    @Query(value =  " SELECT CODPLACTA, " +
                    "        ABS (SALDOINICIAL) AS SALDOINICIAL," + 
                    "        NATUREZASALDOINICIAL," + 
                    "        ABS (DEBITO) AS DEBITO," + 
                    "        ABS (CREDITO) AS CREDITO, "+ 
                    "        ABS (SALDOFINAL) AS SALDOFINAL," + 
                    "        CASE WHEN NATUREZACONTA = 'D' AND ......... continua...                    "               )" + 
                    "       )", nativeQuery = true)
    List<SaldoDeContaContabil> findByVisaoAndPeriodo(
            @Param("CODVSA") String visao,
            @Param("DATINI") LocalDate dataInicial,
            @Param("DATFIN") LocalDate dataFinal,
            @Param("LISTAEMP") String listaDeEmpresas,
            @Param("CODETTPLACTA") Integer estruturaDoPlanoDeContas,
            @Param("LISTANAT") String listaNaturezaDasContas,
            @Param("LISTACONTA") String listaDeContas
            );

Classe de servico

package br.com.atac.erp.model.service;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
//-- imports omitidos

@Service
public class SaldoDeContaContabilService {

    @Autowired
    SaldoDeContaContabilRepository repository;

    public List<SaldoDeContaContabil> findByVisaoAndPeriodo(VisaoContabil visao, Periodo periodo) {

        List<SaldoDeContaContabil> saldos = repository.findByVisaoAndPeriodo(visao.getCodigo(), periodo.getInicio(), periodo.getFim());
        return saldos;
}

O seguinte erro esta sendo apresentado ja no inicio da execucao


APPLICATION FAILED TO START


Description:

Field repository in br.com.xpto.erp.model.service.SaldoDeContaContabilService required a bean of type 'br.com.xpto.erp.model.repository.SaldoDeContaContabilRepository' that could not be found.

The injection point has the following annotations:

- @org.springframework.beans.factory.annotation.Autowired(required=true)

Action:

Consider defining a bean of type 'br.com.xpto.erp.model.repository.SaldoDeContaContabilRepository' in your configuration.

2 respostas

Oi Rui,

Acho que nesse seu caso em específico seria melhor você criar uma classe Dao tradicional, ao invés de utilizar o repository, e nela injetar o EntityManager e montar a query utilizando o esquema do select new da JPA.

Algo como:

@Repository
public class SaldoDeContaContabilDao {

    @PersistenceContext
    private EntityManager manager;

    public List<SaldoDeContaContabil> findByVisaoAndPeriodo(VisaoContabil visao, Periodo periodo) {
        String jpql = "select new br.com.seu.pacote.SaldoDeContaContabil(CODPLACTA, ABS(SALDOINICIAL) AS SALDOINICIAL, .....) from ..... where periodo = :periodo";

        return manager
            .createQuery(jpql, SaldoDeContaContabil.class)
            .setParameter("periodo", periodo)
            .setParameter(...)
            .getResultList();
    }

}

Implementando como DAO e utilizando o EntityManager