Joined-subclass no Hibernate

Estou com um problema com uma subclasse no Hibernate, se alguem souber o que pode ser…

Tenho as seguintes tabelas:

clientes –
id
nome

servicos –
id
nome
valor

servicos_cliente –
id_cliente
id_servico
quantidade

fiz o mapeamento assim…

<hibernate-mapping>
  <class name="Cliente" table="clientes">
     <id name="id" column="id">
       <generator class="increment" />
     </id>
     <property name="nome" column="nome" />

     <bag name="servicos" table="servicos_cliente">
       <key column="id_cliente"/>
       <many-to-many class="ServicoCliente" column="id_servico"/>
     </bag>
  </class>
  
  <class name="Servico" table="servicos">
    <id name="id" column="id">
      <generator class="increment" />
    </id>
    <property name="nome" column="nome" />
    <property name="valor" column="valor" />
    
    <joined-subclass name="ServicoCliente" table="servicos_cliente" dynamic-insert="true" dynamic-update="true">
      <key column="id_servico"/>
      <property name="quantidade" column="quantidade" type="integer" />
     </joined-subclass>
  </class>
</hibernate-mapping>

na classe Cliente tem um List com os servicos, está me retornando certo, porem na hora que eu tento gravar algum objeto cliente, ele não grava a propriedade quantidade de ServicoCliente somente as declaradas em Servico

Obrigado,

Não culpe o Hibernate por isso…:stuck_out_tongue:

Por favor, coloque tb o código pra q a galera possa ajudar…

Abraço.

public class Cliente{
  private int id;
  private String nome;
  private List servicos;  

  public void setId(int id){
    this.id = id;
  }
  public int getId(){
    return id;
  }
  public void setNome(String nome){
    this.nome = nome;
  }
  public String getNome(){
    return nome;
  }
  public void setServicos(List servicos){
    this.servicos = servicos;
  }
  public List getServicos(){
    return servicos;
  }

}


public class Servico(){
  private int id;
  private String nome;
  private double valor;

  public void setId(int id){
    this.id = id;
  }
  public int getId(){
    return id;
  }
  public void setNome(String nome){
    this.nome = nome;
  }
  public String getNome(){
    return nome;
  }
  public void setValor(double valor){
    this.valor = valor;
  }
  public double getValor(){
    return valor;
  }
}
public class ServicoCliente extends Servico{
  private int quantidade;

  public void setQuantidade(int quantidade){
    this.quantidade = quantidade;
  }

  public int getQuantidade(){
    return quantidade;
  }
}

import net.sf.hibernate.*
import net.sf.hibernate.cfg.*;

public class AcessoHibernate{
   private Configuration cfg = new Configuration();
   private SessionFactory factory;

   public AcessoHibernate(){
     configura();
   }

  public configura(){
   Properties prop = new Properties();
    prop.load(getClass().getResourceAsStream("hibernate_config.properties"));
            
    cfg.setProperties(prop);

    cfg.configure(getClass().getResource("hibernate.cfg.xml"));

    factory = cfg.buildSessionFactory();
}

public void insert(Cliente cliente){
   Session session = factory.openSession();
   
   Transaction trans = session.beginTransaction();

   session.save(cliente);
   
   trans.commit();
  
   session.close();
}
}


public class Aplicacao(){
  public static void main(String[] args){
    AcessoHibernate hib = new AcessoHibernate();

   Cliente cli = new Cliente();

   cli.setNome("Nome do cliente");
   ArrayList servicos = new ArrayList();
   ServicoCliente serv = new ServicoCliente();
   serv.setNome("nome do servico");
   serv.setValor(50.0);
   serv.setQuantidade(10);
   servicos.add(serv);
   cli.setServicos(servicos);

}
}

fiz esse codigo aí pra teste, ele insere o cliente, mas na tabela servicos_clientes, ele não grava a quantidade…

Jairelton,

1 - pelo q entendi trata-se de um relacionamento n para n… soh não entendi pq vc usa o joined-subclass ao invés de dois relacionamentos 1 para n com a tag <one-to-many> nas entidades SERVIÇOS e CLIENTE.

2 - Vc tb poderia estar analisando os SQLs gerados pelo Hibernate para saber q raio de valor ele está colocando nesse campo de quantidade.

De qq maneira, poste a solução q vc adotou para seu problema.

Abraço.

André.

Estou usando joined-subclass porque se você observar na tabela intermediaria que faz o relacionamento tem um campo a mais “quantidade”, e na coleção que será criada dentro de “Cliente” eu preciso ter objetos com esse dado, então o objeto seria uma junção dos dados da tabela “servicos” e do campo “quantidade” da tabela “servicos_cliente”

public Class ServicoCliente extends Servico&#123;
   //o que foi herdado de Servico vem da tabela servicos

  private int quantidade; //&lt;-- esse atributo vem da tabela servicos_cliente
&#125;

Uma outro exemplo que talvez seja mais familiar a todos, é de notas fiscais, imaginem uma tabela “produtos”, uma tabela “notas_fiscais” e uma que faz o relacionamento das duas, “itens_notafiscal”, na tabela “itens_notafiscal” eu teria os dois campos que fazem o relaciomento com as outras duas tabelas e um campo “quantidade” que seria a quantidade daquele produto na nota fiscal, como eu faria para mapear isso?

notas_fiscais–
numero_nota
cliente
valor

produtos–
codigo
descricao
preco

itens_notafiscal–
cod_nota
cod_produto
quantidade

eu poderia simplesmente colocar um many-to-many e pronto, mas e o campo quantidade?

tambem não sei se joined-subclass é a forma correta de fazer isso, mas foi o mais proximo que consegui chegar, se alguem tiver alguma ideia…

Obrigado,

Como eu disse…

vc poderia usar o one-to-many. Desse jeito…

Imagine um relacionamento existem N Categorias para N Itens… vc criaria um set em Categorias com essas definições…

&lt;set name=&quot;items&quot; lazy=&quot;true&quot; table=&quot;CATEGORY_ITEMS&quot;&gt;
  &lt;key column=&quot;CATEGORY_ID&quot;/&gt;
  &lt;composite-element class=&quot;CategorizedItem&quot;&gt;
     &lt;parent name=&quot;category&quot;/&gt;
     &lt;many-to-one name=&quot;item&quot;
                          class=&quot;Item&quot;
                          column=&quot;ITEM_ID&quot;
                          not-null=&quot;true&quot;/&gt;
     &lt;property name=&quot;dateAdded&quot; 
                    column=&quot;DATE_ADDED&quot;
                    notnull=&quot;true&quot;/&gt;
  &lt;/composite-element&gt;
&lt;/set&gt;

(Extraído do livro Hibernate In Action)