Duvida ao listar registro no Hibernate qdo há relacionamento [RESOLVIDO]

5 respostas
L

Pessoal, estou com uma duvida… Tenho duas classes relacionadas:

public class FileDriverVO {
    @Id @GeneratedValue
    private Integer id;
    @Column(length=150)
    private String name;
    ...
}
public class DriverVO {
    @Id @GeneratedValue
    private Integer id;
    @Column(length=40)
    private String name;
    @Column(length=50)
    private String dialect;
    @Column(length=80)
    private String driver;
    @Column(length=20)
    private String protocol;
    @Column(length=1)
    private String reservado;
    
    @OneToMany(fetch = FetchType.EAGER, cascade = {CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REMOVE})
    private List<FileDriverVO> files;
    ...

Para retornar todos os dados, faço assim na minha classe DAO:

public List<T> findAll() {
        return this.session.createCriteria(this.classVO.getName()).list();
    }

Qdo chamo o método findAll, ele roda a seguinte instrução SQL:

select
        this_.id as id0_1_,
        this_.dialect as dialect0_1_,
        this_.driver as driver0_1_,
        this_.name as name0_1_,
        this_.protocol as protocol0_1_,
        this_.reservado as reservado0_1_,
        files2_.driver_id as driver1_3_,
        filedriver3_.id as files2_3_,
        filedriver3_.id as id1_0_,
        filedriver3_.name as name1_0_ 
    from
        driver this_ 
    left outer join
        driver_filedrivers files2_ 
            on this_.id=files2_.driver_id 
    left outer join
        filedrivers filedriver3_ 
            on files2_.files_id=filedriver3_.id

A minha dúvida é assim… Eu tenho dois registros na tabela driver e 4 registros na tabela filedrivers (1 registro para o registro 1 da driver e 3 para o registro 2). Só que qdo eu mando carregar os drivers numa JComboBox, ele tá trazendo os 4 registros. Como posso fazer para trazer apenas os dois registros de cabeçalho (driver)?

Obrigado

5 Respostas

Hebert_Coelho

Você está fazendo um findAll correto?
Você terá que buscar, apenas o DriverVO que você quer exibir na sua tela.

entityManager.find(DriverVO.class, 1); // o 1 é o id que você quer procurar

L

Olá, na verdade eu não quero exibir apenas um… Vou tentar explicar melhor:

Tabela Driver:

+----+------------------------------------+---------------------------+-------------------+-----------+
| id | dialect                            | driver                    | name              | reservado |
+----+------------------------------------+---------------------------+-------------------+-----------+
|  1 | org.hibernate.dialect.MySQLDialect | com.mysql.jdbc.Driver     | MySQL JDBC Driver | S         |
|  2 |                                    | com.ibm.db2.jcc.DB2Driver | IBM DB2 Driver    | N         |
+----+------------------------------------+---------------------------+-------------------+-----------+

Tabela FileDriver:

+----+-------------------------------------+
| id | name                                |
+----+-------------------------------------+
|  1 | mysql-connector-java-5.1.13-bin.jar |
|  2 | db2jcc.jar                          |
|  3 | db2jcc_license_cu.jar               |
+----+-------------------------------------+

Tabela Driver_FileDriver:

+-----------+----------+
| driver_id | files_id |
+-----------+----------+
|         1 |        1 |
|         2 |        2 |
|         2 |        3 |
+-----------+----------+

Eu preciso retornar apenas os meus drivers e não tudo… Por exemplo, se eu chamar o meu findAll ele me retorna isto:

+--------+------------------------------------+---------------------------+-------------------+---------------+------------+-----------+--------+-------------------------------------+
| id2_1_ | dialect2_1_                        | driver2_1_                | name2_1_          | reservado2_1_ | driver1_3_ | files2_3_ | id0_0_ | name0_0_                            |
+--------+------------------------------------+---------------------------+-------------------+---------------+------------+-----------+--------+-------------------------------------+
|      1 | org.hibernate.dialect.MySQLDialect | com.mysql.jdbc.Driver     | MySQL JDBC Driver | S             |          1 |         1 |      1 | mysql-connector-java-5.1.13-bin.jar |
|      2 |                                    | com.ibm.db2.jcc.DB2Driver | IBM DB2 Driver    | N             |          2 |         2 |      2 | db2jcc.jar                          |
|      2 |                                    | com.ibm.db2.jcc.DB2Driver | IBM DB2 Driver    | N             |          2 |         3 |      3 | db2jcc_license_cu.jar               |
+--------+------------------------------------+---------------------------+-------------------+---------------+------------+-----------+--------+-------------------------------------+

Mas eu queria que fosse retornado apenas isto:

+--------+------------------------------------+---------------------------+-------------------+---------------+
| id2_1_ | dialect2_1_                        | driver2_1_                | name2_1_          | reservado2_1_ |
+--------+------------------------------------+---------------------------+-------------------+---------------+
|      1 | org.hibernate.dialect.MySQLDialect | com.mysql.jdbc.Driver     | MySQL JDBC Driver | S             |
|      2 |                                    | com.ibm.db2.jcc.DB2Driver | IBM DB2 Driver    | N             |
+--------+------------------------------------+---------------------------+-------------------+---------------+

Como eu deveria implementar?

fbl.lucas

coloca:

L

ISto mesmo fbl.lucas … Tentei da segunda forma e deu certo… Só uma dúvida: qual a diferença entre o LAZY e o EAGER?

[]s

fbl.lucas

libajunior:
ISto mesmo fbl.lucas … Tentei da segunda forma e deu certo… Só uma dúvida: qual a diferença entre o LAZY e o EAGER?

[]s


LAZY carrega a lista de files sobre demanda, ou seja, quando você faz a consulta de DriverVO ele não trás a lista de FileDriverVO mas quando você fizer um getFiles o hibernate vai até o banco e trás a lista para você… é considerada uma boa prática como tudo como LAZY, trás grandes ganhos de performance.
Já o EAGER trás a lista populada na primeira consulta, é recomendado quando por exemplo você sempre for precisar acessar os dados deste objeto/lista.

Criado 2 de janeiro de 2012
Ultima resposta 3 de jan. de 2012
Respostas 5
Participantes 3