Duvida em Relacionamento ManyToMany

Boa noite galera,
Estou com um duvida, faz um tempo, e n consigo sanar ela na net

tenho esse relacionamento, ele se repete com Enfermeiro
Captura%20de%20tela%20de%202019-06-30%2023-33-46

Estou iniciando do Hibernate
Estou precisando popular uma tabela de plantões

public class PlantaoTable extends TableTemplate<Pessoa> {

    private List<Pessoa> pessoa;

    @Override
    public void clearTable() {
        pessoa = new ArrayList();
        this.fireTableDataChanged();
    }

    static class Constantes {

        private static final String[] COLUNAS = {"Nome", "Data Nacimento", "Telefone", "Identificador", "Função"};
        private static final int NOME = 0;
        private static final int NASCIMENTO = 1;
        private static final int TELEFONE = 2;
        private static final int IDENTIFICADOR = 3;
        private static final int FUNCAO = 4;
    }

    @Override
    public Object getValueAt(int rowIndex, int columnIndex) {
        String funcao = "";
        String identificador = "";
        String horarioPlantao = "";
        if (pessoa.get(rowIndex) instanceof Medico) {
            funcao = "Médico";
            Medico m = (Medico) pessoa.get(rowIndex);
            identificador = m.getCrm();
            horarioPlantao = Utils.dateHoraToString(m.getPlantaos().get(0).getData());
        }
        if (pessoa.get(rowIndex) instanceof Enfermeiro) {
            funcao = "Enfermeiro";
            identificador = ((Enfermeiro) pessoa.get(rowIndex)).getCorenCofen();
        }
        switch (columnIndex) {
            case Constantes.NOME:
                return pessoa.get(rowIndex).getNome();
            case Constantes.NASCIMENTO:
                return Utils.dateToString(pessoa.get(rowIndex).getDataNascimento());
            case Constantes.TELEFONE:
                return pessoa.get(rowIndex).getTelefone();
            case Constantes.IDENTIFICADOR:
                return identificador;
            case Constantes.FUNCAO:
                return funcao;
            default:
                return null;
        }
    }

    @Override
    public Pessoa getRow(int row) {
        return row >= 0 ? pessoa.get(row) : null;
    }

    @Override
    public String getColumnName(int column) {
        return Constantes.COLUNAS[column];
    }

    @Override
    public void addRow(Pessoa obj) {
        pessoa.add(obj);
        this.fireTableDataChanged();
    }

    @Override
    public void removeRow(int row) {
        pessoa.remove(row);
        this.fireTableRowsUpdated(row, row);
        this.fireTableDataChanged();
    }

    @Override
    public void updateRow(Pessoa obj, int row) {
        pessoa.set(row, obj);
        this.fireTableRowsUpdated(row, row);
        this.fireTableDataChanged();
    }

    @Override
    public int getRowCount() {
        return pessoa.size();
    }

    @Override
    public int getColumnCount() {
        return Constantes.COLUNAS.length;
    }

}

to precisando adicionar o horario do plantao na tabela, mas o problema é q por exemplo , um medico tem um lista de plantao, e um plantao tem uma lista de medicos, ai como eu faço para pegar um medico por plantao, ai sabendo q no select so vai vir 1 plantao posso dar getPlantaos().get(0).getData()

Select m from Medico as m LEFT JOIN m.plantaos
Assim consigo pegar os medicos que tenham plantao e colocar na tabela, mais fica muito repetido e queria mostrar o horario do plantao tmb, mas quem tem o horario e a tabela plantao

Trata-se de uma relação bidirecional de muitos para muitos, não?
Mas e se você buscar pela tabela Plantao, passando data e hora como parâmetro da busca? Assim você lista todos os médicos daquele plantão…

eu particularmente não usaria o @ManyToMany. Criaria uma classe MedicoPlantao e a mapearia com o OneToMany de Medico e Plantão, substituindo essa tabela medico_has_plantao. Colocaria um ID sem ser chave composta entre medico e plantão.

Na classe plantão e medico, você teria um array dessa classe MedicoPlantao. E colocaria os atributos que quiser nela.

Como disse, eu faria assim. Porque usando @ManyToMany, monta apenas uma tabela (medico_has_plantao) que so pega o ID de cada uma, caso queira colocar mais atributos, nao teria como, pelo menos eu nao sei como.

Um exemplo seria um cadastro de produto que varias empresas utilizariam. eu teria que ter uma tabela empresa_has_produto. Porem, cada empresa tem seu preco, sua tributacao, seu estoque.
Usando o @ManyToMany, eu nao conseguiria colocar os campos especificos que surgem desse relacionamento.

Entao crio 3 classes: Produto - ProdutoEmrpesa - Empresa, e mapeio como relacionamento de 1 para muitos.

Você pode manter a estrutura atual e criar uma tabela para ser a tabela associativa, inclusive, incluindo mais atributos.

editei minha resposta. para ficar menos confusa. :slight_smile:

acho que não fui claro na duvida,

meu problema é q quando pesquiso no banco um plantao ou um medico é q por exemplo

medico João tem plantao terça, e quinta
medica Amanda tem plantao segunda e quinta

ai ao listar plantões, e de terça vem joao e amanda, até ai td certo, ai quando vou usar esses dados o joão vem com todos os plantões dele (terça e quinta) ai na hora de lista na tabela n sei qual plantao colocar pegar

acho q tenho e mudar as anotações das entidades para trazer somente 1 elemento

olha como elas estão
@ManyToMany(mappedBy = “medicos”, targetEntity = Plantao.class, fetch = FetchType.EAGER, cascade = CascadeType.ALL)
@Fetch(value = FetchMode.SUBSELECT)
private List plantaos;

@ManyToMany
    @JoinTable(name = "plantao_medico",
            joinColumns = @JoinColumn(name = "idPlantao"),
            inverseJoinColumns = @JoinColumn(name = "idMedico"))
    private Set<Medico> medicos;

resumidamente, eu quero q ao listar os plantões, ele me traga todos os medicos que tem plantões, mas n quero que os medicos venham com todos os plantões que possuem

Use um lazy load no List na classe medicos

se eu colocar fetch = FetchType.LAZY na lista de plantaos de medicos da erro

: failed to lazily initialize a collection of role

Construa uma quero com Join e indique quais são as restrições: médico = “João” e data = “quinta”

O erro do lazy eh pq voce deve estar fazendo alguma consulta em medico.getPlantoes();

se vc pedir todos os plantoes de um dia, e colocar plantoes.medico.nome, … nao da lazy load.
sugiro o que o colega falou faca uma lista que recupere plantoes. ai no plantao, vc tem acesso aos dados de cada medico. nesse caso, vc recebera um objeto plantao ou uma lista de plantoes.
ai vc faz

for (Plantao plantao: plantoes)   {
        for (Medico medico : plantao.getMedicos()) {
        plantao.getData();
        medico.getNome();
    }
}

se em algum momento voce precisar o dos plantoes de um unico medido, voce cria um metodo que receba um medico e retorne os plantoes dele. Assim voce joga o relacionamento dos plantoes de um medido em FetchType.LAZY. e pode deixar os medicos no relacionamento de plantao como EAGER

eu não consigo explicar minha duvida :roll_eyes:

eu quero colocar Data do plantao na AbstractTable, simplificando

Desisti, coloquei para o usuario pesquisar a data do plantao, ai listo, os funcionarios q estão de plantao nesta data, assim não preciso colocar a data na table

Cara, não sei se isso aqui te ajudaria, mas não custa nada postar aqui para você dar uma olhada:

Veja a mensagem ai do discorpio, ele solucionou um problema que creio que seja o seu também. :wink: