Dúvida com retorno de consulta HQL (Hibernate)

Pessoal,

Tenho duas entidades:

Produto
ProdutoCodigoBarras

Um único produto (esmalte marca X) pode ter 1 ou mais que 1 códigos de barras relacionados a ele. Isso foi feito para que o cliente não tivesse a necessidade de cadastrar todas as variações de esmalte, por exemplo. Nesse caso ele cadastra apenas um esmalte e depois faz a ligação deste com todos os códigos de barras para tal modelo de esmalte (que normalmente só muda a cor). Ou seja, a entidade ProdutoCodigoBarras possui apenas os atributos:

produto (Produto que possui este código)
codigoBarras (O código de barras)

Estou tentando executar a consulta abaixo:

result = session.find( "from produto in class tisc.multuspdv.beans.Produto " + "inner join produto.codigoBarras codigobarras where " + "codigobarras.codigoBarras like ?", codigoBarras + "%", Hibernate.STRING );

Até ai tudo bem, a consulta é executada e retorna dados corretamente do BD (sei disso executando um result.size() e comparando com o que tenho realmente no banco).

O problema é que na mesma classe ProdutoDAO eu tenho outras consultas que não possuem JOIN e nesse caso elas retornam apenas instâncias de Produto. A consulta exibida acima retorna um array de Object (onde em uma posição tem-se o Produto e em outra o ProdutoCodigoBarras. Isso é normal? Não existe forma com o JOIN de apenas ser retornado instâncias de Produto e eu acessar os códigos de barras chamando um método como getCodigosBarras()???

Agradeço qualquer ajuda!

Paulo Oliveira

é so expecificar:

select produto from produto in class tisc.multuspdv.beans.Produto 
inner join produto.codigoBarras codigobarras where codigobarras.codigoBarras like ?

agora outra forma de fazer isso (eu acho mais correto):

from tisc.multuspdv.beans.Produto as produto
where produto.codigobarras.codigoBarras like ?

nesse caso, o hibernate vai comparar as chaves de produto com o codigoBarras sozinho…

Olá Maximiliano,

Obrigado pela ajuda…

Funcionou da primeira forma (com o JOIN)…

Da segunda forma, a seguinte exceção é lançada:

Exception in thread "AWT-EventQueue-0" java.lang.RuntimeException: expecting 'elements' or 'indices' after: codigoBarras [from tisc.multuspdv.beans.Produto as produto where produto.codigoBarras.codigoBarras like '789%'

Vi aqui que ele dá esse erro por conta desse último “.codigoBarras”, é como se ele esperasse por outra coisa, e não por uma PROPRIEDADE do BEAN ProdutoCodigoBarras.

Um abraço,

Paulo Oliveira

mas esse ultimo codigo de barras é uma lista? ou set ? ou alguma forma de collection?

pq se for, tem q fazer: elements(produto.codigoBarras.codigoBarras) like ?

se nao for, deve ser alguma coisa na tua configuracao, tipo:
hibernate.cglib.use_reflection_optimizer=true
use_outer_join=true

Olá Max,

Não… Esse último codigoBarras é String. O penúltimo (que é membro da classe Produto) é que é um Set.

Vou listar esses dois Beans problemáticos :slight_smile:

Produto.java

public class Produto {

    // Campos existentes na tabela
    private Integer       idProduto;
    private String        descricao;
    private String        descricaoResumida;
    private Marca         marca;
    private Secao         secao;
    private Float         vendaMedida;
    private UnidadeMedida vendaUnidadeMedida;
    private Float         preco;
    private Integer       estoque;
    private Float         vasilhameMedida;
    private UnidadeMedida vasilhameUnidadeMedida;
    private Tributo       tributo;

    // Relacionamentos um-para-muitos
    private Set           codigoBarras;

    // Aqui viriam os GETTERS e SETTERS
    ...

E agora a outra classe:

public class ProdutoCodigoBarras {

    private String  codigoBarras;
    private Produto produto;

    // Aqui viriam os GETTERS e SETTERS
    ...

E meus .hbm.xml:

<hibernate-mapping>

    <class name="tisc.multuspdv.beans.Produto" table="tb_produto">
    	
    	<!-- Chave primária -->
    	<id name="idProduto" column="id" type="int">
    		<generator class="native">
    			<param name="sequence">tb_produto_id_seq</param>
    		</generator>
    	</id>
    	
    	<!-- Atributos -->
        <property name="descricao"         column="prod_descricao"          not-null="true"  length="50" />
        <property name="descricaoResumida" column="prod_descricao_resumida" not-null="false" length="24" />
        <property name="estoque"           column="prod_estoque"            not-null="false"             />
        <property name="preco"             column="prod_preco"              not-null="false"             />
        <property name="vasilhameMedida"   column="prod_vasilhame_medida"   not-null="false"             />
        <property name="vendaMedida"       column="prod_venda_medida"       not-null="false"             />
        
        <!-- Relacionamentos muitos-para-um -->
        <many-to-one name="marca"                  column="prod_marca"                    not-null="false" />
        <many-to-one name="tributo"                column="prod_tributo"                  not-null="true"  />
        <many-to-one name="vasilhameUnidadeMedida" column="prod_vasilhame_unidade_medida" not-null="false" />
        <many-to-one name="vendaUnidadeMedida"     column="prod_venda_unidade_medida"     not-null="false" />
        <many-to-one name="secao"                  column="prod_secao"                    not-null="true"  />
        
        <!-- Relacionamentos um-para-muitos -->
        <set name="codigoBarras" inverse="true" lazy="true">
            <key column="pcbr_produto" />
            <one-to-many class="tisc.multuspdv.beans.ProdutoCodigoBarras" />
        </set>
        
    </class>

</hibernate-mapping>

E o outro:

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
   "-//Hibernate/Hibernate Mapping DTD//EN"
   "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">

<hibernate-mapping>
    <class name="tisc.multuspdv.beans.ProdutoCodigoBarras" table="tb_produto_codigo_barras">
    	
    	<!-- Chave primária -->
    	<id name="codigoBarras" column="pcbr_codigo_barras" type="string">
        	<generator class="assigned" />
        </id>
        
    	<!-- Relacionamentos -->
        <many-to-one name="produto" column="pcbr_produto" not-null="true" />
        
    </class>

</hibernate-mapping>

Alguma luz? :slight_smile:

Grande abraço e muitíssimo obrigado!

Paulo Oliveira

sempre deve-se fazer relacoes muitos para 1… evistar o 1 para mutios (set)
pq o hibernate por default levanta todos os relacionamentos… (so se tu setar lazy=true q nao)

entao, quando tu levanta PRODUTOS, to levanta todos os set juntos, e os sets desses sets… nao vai demorar muito pra ti levantar todo o banco de dados para a memoria :slight_smile:

e o select tu faz ao contrario:
select b.produto from CodigoBarras as b where b.codigoBarra like ?

Oi Max…

Muito obrigado pela ajuda… :wink:

Irei testar agora o SELECT “ao contrário”…

Com relação ao LAZY, eu já o coloquei como TRUE…

E com relação ao HIBERNATE, apesar de já ter percebido que é um excelente framework, vou começar a repensar se realmente vale a pena usá-lo (custo/benefício).

Não quero começar a ter que refazer minhas regras de modelagem de dados por causa de um framework. :?

Grande abraço,

Paulo Oliveira