Inserção de dados de arquivo excel

Bom dia,

Estou fazendo um código em JAVA que importa um arquivo Excel e preenche o banco de dados e o sistema.
Porém, estou com dificuldades, quando a tabela possui uma chave estrangeira.
Pensei em fazer com @Query, mas como, vou identificar o dado que tem na planilha com a coluna do banco para fazer a condição?

1 curtida

FK é uma coluna normal de uma tabela de um banco de dados, não? A única diferença é que ela referencia o identificador (PK) de uma outra tabela.
Qual a dificuldade nisso? Não entendi.

A coluna FK da tabela está como ID_‘coluna’, que seria o identificador.
No arquivo excel, o usuário vai digitar o nome da pessoa, que pertence a esse ID_‘coluna’.
Então, vai ter que identificar o nome que foi digitado e a qual ID pertence, e jogar na tabela original que tem a FK esse ID.

Não sei se deu pra explicar melhor…

Grande parte das inconsistências de dados é devida a falhas na inserção das informações por parte de pessoas.
Existe meio que uma lei no mundo do desenvolvimento que é mais ou menos assim: nunca confie no usuário.
Logo, desenvolvendo a solução desta maneira, você está dando brechas para que teu sistema falhe miseravelmente, pois o usuário pode, de maneira proposital ou não, confundir os dados, inserir cosias erradas e você jamais terá como garantir se o que foi digitado pelo usuário é ou não condizente com a realidade.
Além disso, a ideia de PK e FK é garantir uma coisa chamada integridade, afinal, associa a informação da tabela X à tabela Y. Mais além, a PK é uma garantia que aquela linha específica (tupla) seja única, por algum motivo.
Você não precisa, necessariamente, que uma PK seja numérica e auto incrementável, mas, que ela seja única.
Agora, pense, João da Silva é um nome único? Certamente, não. Como vai garantir que o nome associado a um ID que representa a FK é daquela pessoa?
Isso só para ficar em um exemplo.

Entendi seu ponto de vista.
Na minha situação, os dados da tabela onde contém a chave FK já existem.(ID,nome,…)
Que são os dados do gestor.
Essa importação do excel é um plus, caso, cliente queira importar para uma outra tabela.
O nome do gestor que estiver na planilha, já existe no banco, ele só vai verificar qual o ID que ele representa para preencher a outra tabela.

Acredito que o cliente final dele estará de acordo com as normas e funcionalidades do projeto…
em uma corporativa de grande porte onde os clientes estão de acordo com o contrato e com as mecânicas do projeto dificilmente haverá erros de inserção errada na tabela, afinal o modelo padrão é usado como base.

bom deixando isso de lado … acredito que ele deveria usar algo como uma Query.
exemplo:

@Query(value = "select * from grouping where Name like :name", nativeQuery = true)
Grouping findByName(@Param("name") String name); 

algo do gênero, como sou desenvolvedor iniciante ainda tenho muitas duvidas, mas acredito que cada projeto tem sua aplicação contendo riscos ou não.

Eu insisto que não se deve confiar no cliente. Se o xls fosse gerado por outro sistema, ok, pois seguiria padrões e você teria um meio termo. Quando depende de interação humana, eu fico com o pé atrás.

Se você amarrar pelo ID, é outra história. Pois, nesta situação, você consegue validar antes de concretizar a importação (vai ser um tanto trabalhoso, buscar no banco, deixar em memória, validar se você tem um dado válido (id, nome, etc) ou não (inconsistência).

Eu passei pelo mesmo problema a um tempo, o que eu fiz, quando o usuário inserir o valor, eu faço a busca no banco de dados (do nome da pessoa) e trago o FK, que no seu caso é o ID, só que caso tenha um nome incorreto, aquele dado não seria inserido, podendo gerar inconsistência de dados, dado esse problema, eu passei a inserir todos os meus dados em uma lista, fazendo todas as verificações possíveis e caso tenha erro em qualquer dado, é exibido pro usuário o que está errado e em qual linha está o erro e nenhum dado é inserido no BD, caso estejam todos corretos, eu insiro a lista completa no BD.

No case 6 e 10 são feitas as consultas que mencionei.

Segue o código:

public void handleFileUpload(FileUploadEvent event) throws IOException {
    int i = 0;

    try {
        /* pega o arquivo Excel */
        Workbook workbook = null;
        
        if (event.getFile().getFileName().contains("xlsx")) {
            try {
                workbook = new XSSFWorkbook(event.getFile().getInputstream());
            } catch (IOException ex) {
                throw new RuntimeException(ex);
            }
        } else if (event.getFile().getFileName().contains("xls")) {
            try {
                workbook = new HSSFWorkbook(event.getFile().getInputstream());
            } catch (IOException ex) {
                throw new RuntimeException(ex);
            }
        }
        /* pega a primeira planilha dentro do arquivo XLS */
        Sheet sheet = workbook.getSheetAt(0); 
        
        //Pega a quantidade de linhas da planilha
        Iterator<Row> rowIterator = sheet.iterator();
        List<MovCapex> listMC = new ArrayList<> ();
        while (rowIterator.hasNext()) {
            i++;
            Row row = rowIterator.next();
            Iterator<Cell> cellIterator = row.cellIterator();
            MovCapex movCapex = new MovCapex();
            String s = null;
            while (cellIterator.hasNext()) {
                Cell cell = cellIterator.next();
                switch (cell.getColumnIndex()) {
                    case 0:
                        movCapex.setDataCd(cell.getDateCellValue());
                        break;
                    case 1:
                        movCapex.setDataRef(cell.getStringCellValue());
                        break;
                    case 2:
                        movCapex.setOdex(String.valueOf((int)cell.getNumericCellValue()));
                        break;
                    case 3:
                        movCapex.setObrasTerceiros(cell.getStringCellValue());
                        break;
                    case 4:
                        movCapex.setAssunto(cell.getStringCellValue());
                        break;
                    case 5:
                        movCapex.setDescricaoOdex(cell.getStringCellValue());
                        break;
                    case 6:
                        Cr cr = ejbFacade.consultarCr(cell.getNumericCellValue());
                        if(cr == null) {
                            JsfUtil.addErrorMessage("Cr " + cell.getStringCellValue() + " não existe");
                            throw new IllegalStateException();
                        }
                        movCapex.setCr(cr);
                        break;
                    case 7:
                        movCapex.setValor(new BigDecimal (cell.getNumericCellValue()));
                        break;
                    case 8:
                        movCapex.setNatureza(cell.getStringCellValue());
                        break;
                    case 9:
                        s = cell.getStringCellValue();
                        break;
                    case 10:
                        ClassTaxonomia tax = ejbFacade.consultarTaxonomia(s, cell.getStringCellValue());
                        if(tax == null) {
                            JsfUtil.addErrorMessage("Taxonomia " + s + " - " + cell.getStringCellValue() + " não existe");
                            throw new IllegalStateException();
                        }
                        movCapex.setIdClassTaxonomia(tax);
                        break;
                 }
            }
            listMC.add(movCapex);
        }
        
        for(MovCapex tmp : listMC) {
            getFacade().create(tmp);
        }
                            

        workbook.close();
        
        JsfUtil.addSuccessMessage("Envio do arquivo " + event.getFile().getFileName() + " realizado com sucesso!");
        
     } catch (FileNotFoundException e) {
        JsfUtil.addErrorMessage("Arquivo não encontrado");
    } catch (IllegalStateException e) {
        JsfUtil.addErrorMessage("Erro de dado, existem dados incorretos na linha "+ i + " da planilha.");
    }
        
}

Curiosidade: como trata homônimos (nomes iguais para pessoas diferentes)?

Ai isso é um problema da definição do escopo dele, o certo seria por uma PK, no caso de cadastro de pessoas, CPF.