Senhores, iniciei com Webflux recentemente e estou com um baita problema.
Quando usava o hibernate + CrudRepository para mapear minhas entidades, a coisa era simples:
-
Entidade Funcionario
-
Entidade Departamento
No caso acima, Funcionario possui um objeto do tipo Departamento e o Hibernate faz toda a magica do JOIN entre as tabelas, e o CrudRepository me devolve um objeto Funcionario ja com o objeto Departamento preenchido com um simples “findById(…)”
Percebi que no mundo reativo do Webflux, isso nao eh tao simples.
Consegui fazer uma consulta na tabela Funcionario, ja preenchendo os dados de departamento dessa forma
public static final BiFunction<Row, RowMetadata, Employe> MAPPING_FUNCTION = (row, rowMetaData) -> Employe.builder()
.id(row.get("emp_id", Integer.class))
.nome(row.get("nome", String.class))
.idade(row.get("idade", Integer.class))
.departamentoObjeto(Department.builder()
.id(row.get("dept_no", String.class))
.descricao(row.get("dept_name", String.class))
.build())
.build();
public Flux<Employe> listarTodos() {
return this.databaseClient
.sql("SELECT * FROM employee em INNER JOIN departments dp ON em.id_department = dp.dept_no ")
.map(MAPPING_FUNCTION)
.all();
}
Existe uma forma mais facil de fazer uma consulta em Funcionarios, ja preenchendo o objeto departamento usando querys???
Faz o SQL já com os joins necessários pra consulta requisitada e joga direto em um DTO, que deverá ter uma estrutura de dados que represente esse resultado. Isso evita ficar travado em mágicas de mapeamentos pra cada situação específica. E também ao invés de ter um objeto departamento, faz o join da tabela departamento no SQL e coloca o nome do departamento direto nesse DTO, fica muito mais prático.
1 curtida
Você tem algum exemplo de como poderia fazer isso?
Mas se eu entendi, automaticamente (como eh feito no hibernate) não tem como certo?
public static final BiFunction<Row, RowMetadata, Employe> MAPPING_FUNCTION = (row, rowMetaData) -> Employe.builder()
.id(row.get("emp_id", Integer.class))
.nome(row.get("nome", String.class))
.idade(row.get("idade", Integer.class))
.idDepartamento(row.get("dept_no", Integer.class))
.nomeDepartamento(row.get("dept_name", String.class))
.build();
public Flux<Employe> listarTodos() {
return this.databaseClient
.sql("SELECT em.emp_id, em.nome, em.idade, dp.dept_no, dp.dept_name "
+ "FROM employee em "
+ "INNER JOIN departments dp ON em.id_department = dp.dept_no ")
.map(MAPPING_FUNCTION)
.all();
}
Estrutura de dados:
public class Employe {
private Integer id;
private String nome;
private Integer idade;
private Integer idDepartamento; /* retirar daqui e do SQL caso não for necessário para a consulta */
private String nomeDepartamento;
}
É só para ilustrar a ideia, se baseando no seu próprio código, o que faltar você completa.
Importante que cada funcionalidade diferente tenha sua própria SQL e estruturade dados. Ao invés do nome Employe, pode dar um nome mais específico pra consulta. Do contrário, misturar responsabilidades sempre dá m***. Ai fica aquele terror que se mexer na classe tal pode impactar o sistema inteiro.
Ah acho que saquei
O lance eh que com Webflux eu tenho que esquecer o mundo maravilhoso do Hibernate e ser mais raiz kkkk
Vou deixar o POST aberto mais um tempo pra ver se surge mais alguma resposta, e qlqr coisa finalizo ele com a sua
Valeeu
Eu uso JdbcTemplate, acho hibernate um mundo horrível, muito overhead.
Usei muito JDBCTemplate, eh bem fácil de usar.
O problema eh que eu preciso montar a query e o mapeamento campo a campo na mão.
Usando o Hibernate e a interface CrudRepository, eu executo, por exemplo, o método findAll() e ele me traz todos os registros do banco mapeados sem eu ter escrito uma query ou mapeamento…
Achei que no Webflux ia ter algo parecido, mas vi que o caminho eh mais sofrido rs
É, mas tudo tem seu preço. Hibernate tem bem mais overhead, começando por aquele pesado SessionFactory que fica a vida toda na memória da aplicação. Pra alta escalabilidade aumenta o custo na nuvem.
Métodos mágicos como findAll são mais pra sistemas de pequeno porte. Pra empresas de grande porte ou negócios complexos, a realidade do dia a dia são consultas complexas com muitos filtros. Então pelo menos pra mim isso nao faz diferença. O JdbcTemplate mapeia automático através da classe BeanPropertyRowMapper, pode pesquisar se tem equivalente pra WebFlux.