Solucionado (ver solução)
Solucionado
(ver solução)
9
respostas

[Dúvida] existe uma forma automática de fazer a query com jpa? ajuda

tenho este método no repository (eu faço foreach e chamo pra cada aluno da minha lista, o repository, só que queria apagar tudo de uma vez pra não ficar fazendo varias consultas)

@Transactional
@Modifying
@Query("DELETE FROM sala s WHERE s.sala.id = :idSala AND s.aluno.id = :alunoId")

onde eu recebo uma lista de alunos, q são vinculados a uma sala, e quero deletar na tabela sala_alunos todos os registro dela que tenham o mesmo id da sala e o id dos alunos da lista, como faço isso automático no jpa? sem precisar da query?

9 respostas

Olá, Jade!

Sim, para isso, você pode passar uma lista de ids de alunos para o método do repository ao invés de um único id de aluno.

Aqui está um exemplo de como você pode fazer isso:

@Transactional
@Modifying
@Query("DELETE FROM sala s WHERE s.sala.id = :idSala AND s.aluno.id IN :alunosIds")
void deleteInBatch(@Param("idSala") Long idSala, @Param("alunosIds") List<Long> alunosIds);

Neste caso, o método deleteInBatch recebe o id da sala e uma lista de ids dos alunos que você deseja remover. A cláusula IN na query permite que você passe uma lista de valores para o parâmetro, então o JPA irá deletar todos os registros que correspondam ao id da sala e que o id do aluno esteja na lista de alunosIds.

Espero ter ajudado e bons estudos!

void deleteInBatchBySalaIdAndAlunoIdIn(Long salaId, List alunosIds);

tentei isso e dá erro, precisa ser o mesmo nome q ta na entitdade? na entidade ta salaEntity

Uma dúvida, esse seu relacionamento entre sala e alunos é many to many?

Acho que sim e que você quer apenas "remover os alunos da sala", ou seja, remover os registros da tabela de join, mas sem apagar a sala e nem os alunos, correto?

Se for isso, o código anterior está incorreto, pois ele vai apagar a sala da tabela.

ManyToOne eu quero apagar na tabela de join, tipo toda sala (meu endpoint recebe long id), e todos os alunos relacionados nessa sala (meu endpoint recebe um list de long id)

mas aquele metodo q lhe mandei, realmente ta incorreto, ele apaga as salas com o id q coloco, ele não valida os dois parametros, deve ter o id da sala e o id do aluno na tabela de join, o que faço?

Blz, manda aqui essas suas classes para eu entender melhor como ta mapeado e te ajudar nessa query de exclusão

@AllArgsConstructor
@NoArgsConstructor
@Builder
@Data
@Entity
@Table(name = "sala_aluno")
public class SalaAlunoEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name="id")
    private Long id;
    @ManyToOne
    @JoinColumn(name = "id_sala")
    private SalaEntity salaEntity;
    @ManyToOne
    @JoinColumn(name = "id_aluno")
    private AlunoEntity aluno;
    @Column(name = "observacao")
    private String observation;
    @Column(name = "formatura")
    private LocalDateTime dateForm;
}
@Table(name = "sala")
@Entity
public class SalaEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private Long id;
    @Column(name = "bloco")
    private String bloco;
    @OneToMany(mappedBy = "salaEntity")
    private List<SalaAlunoEntity> salaAluno;
}

Acho que a query deve ficar assim então:

@Transactional
@Modifying
@Query("DELETE FROM SalaAlunoEntity s WHERE s.salaEntity.id = :idSala AND s.aluno.id IN :alunosIds")
void deleteInBatch(Long idSala, List<Long> alunosIds);

Dessa forma você pode chamar esse método diretamente, passando o id da sala e os ids dos alunos, sem precisar carregar do banco nem a sala e nem os alunos, tendo uma melhor performance nessa operação.

neste caso, como é list só é possível excluir com o @query? com o metodo daquela forma com jpa não é viavel?

solução!

Com @Query é melhor, para não ter que carregar toda a lista de alunos para a memória.

Quer mergulhar em tecnologia e aprendizagem?

Receba a newsletter que o nosso CEO escreve pessoalmente, com insights do mercado de trabalho, ciência e desenvolvimento de software