Solucionado (ver solução)
Solucionado
(ver solução)
6
respostas

Relacionamento Many-To-One (Bidirecional) x Many-To-Many

Boa tarde,

Segue mais uma dúvida na qual surgiu ao término do curso (lembrando que todas as atividades que acompanhei resultaram com sucesso nas execuções).

Vamos considerar que eu tenho duas entidades Iniciais: Produto e Categoria. Sabendo que um Produto pode possuir apenas uma Categoria, e em sua Tabela será adicionada uma chave estrangeira. Já a Categoria, pode estar contida em N Produtos, não sendo necessária a adição de uma chave na mesma. Agora no momento de Listagem, gostaria de visualizar os Produtos de uma certa Categoria. Os fontes Entidades x Mapeamentos rodaram (funcionando normal) da seguinte maneira:

Entidade Produto:

  public class Produto {
        public virtual int Id { get; set; }
        public virtual string Nome { get; set; }
        public virtual double Preco { get; set; }
        public virtual Categoria Categoria { get; set; }
    }

Mapeamento Produto:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
                   assembly="prjNHibernate_Caelum"
                   namespace="prjNHibernate_Caelum.Entidades">

  <class name="Produto">
    <cache usage="nonstrict-read-write"/>
    <id name="Id">
      <generator class="identity"/>
    </id>

    <property name="Nome"/>
    <property name="Preco"/>
    <many-to-one name="Categoria" column="CategoriaId" fetch="join"/>
  </class>
</hibernate-mapping>

Entidade Categoria:

 public class Categoria {
        public virtual int Id {get; set;}
        public virtual string Nome { get; set; }
        public virtual IList<Produto> Produtos { get; set; }

    }

Mapeamento Categoria:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
                   assembly="prjNHibernate_Caelum"
                   namespace="prjNHibernate_Caelum.Entidades">

  <class name="Categoria">
    <cache usage="nonstrict-read-write"/>
    <id name="Id">
      <generator class="identity"/>
    </id>

    <property name="Nome"/>

    <bag name="Produtos" fetch="join" batch-size="10">
      <cache usage="nonstrict-read-write"/>
      <key column="CategoriaId"/>
      <one-to-many class="Produto"/>
    </bag>
  </class>
</hibernate-mapping>

Percebam que adicionei as Tags de relacionamentos em ambos os locais. Agora consideremos que terei uma nova Entidade chamada Vendas, abaixo seguem os Fontes de Entidade + Mapeamento (Venda):

public class Venda {
        public virtual int Id { get; set; }
        public virtual Usuario Cliente { get; set; }
        public virtual IList<Produto> Produtos { get; set; }
        public Venda(){
            this.Produtos = new List<Produto>();
        }
    }

Mapeamento...

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
                   assembly="prjNHibernate_Caelum"
                   namespace="prjNHibernate_Caelum.Entidades">
  <class name="Venda">
    <id name="Id">
      <generator class="identity" />
    </id>
    <many-to-one name="Cliente" column="ClienteId" />
    <bag name="Produtos" table="Venda_Produtos">
      <key column="VendaId" />
      <many-to-many column="ProdutoId" class="Produto" />
    </bag>
  </class>
</hibernate-mapping>

Minha dúvida é a seguinte: nesse caso da Venda, terei uma tabela adicional "Venda_Produtos", mas na Entidade de Produtos não alterei nada, inclusive em aula não foi solicitado nenhuma inclusão. Não se faz necessário adicionar no Mapeamento de Produto (assim como na Entidade) Tags referenciando o relacionamento também Many-To-Many? Sendo que o Relacionamento é Bi-Direcional (assim como no caso do Relacionamento Produto x Categoria).

Dessa forma o NHibernate criou tudo certinho, mas fiquei na dúvida pois sendo Bi-Direcional imaginei que ambas as Classes + Mapeamentos deveriam ter essa referências também, assim como o primeiro caso.

Aguardo, abraços.

6 respostas

Olá Adriano,

não precisa ser sempre bi-direcional, os relacionamentos podem ser unidirecionais. Se o mapeamento no xml foi feito certinho, ele consegue criar as tabelas e fazer os relacionamentos, mesmo que apenas uma das classes mantenha a relação.

Entendi.

E acaso eu quisesse listar as vendas que certo produto esteja contido? Precisaria criar um IList na Entidade Produto do tipo Venda_Produtos? E no xml precisaria criar esse relacionamento bi-direcional?

Na verdade você adicionaria direto uma List para Venda, porque do lado do servidor você foca em trabalhar com as classes mesmo. Ai teria que configurar no xml para ele fazer o mapeamento com a tabela Venda_Produtos

Entendi certinho.

Contudo, para fins documentar esse caso que apontei, conseguiria me mostrar no fonte como ficariam a Entidade de Venda e seu mapeamento (caso deseje saber os produtos e quantas vendas cada um está relacionado) ?

Obs: sei que o comum é o inverso, a venda e produtos, contudo estou simulando esse caso para maiores detalhamentos.

Abs.

solução!

Então, na verdade o mapeamento do lado da Venda é basicamente aquele que você mandou lá em cima, do xml fazer o bag e na classe adicionar a List. Para ficar bi direcional, só fazer o mesmo processo do lado do Produto, de mexer no xml uma bag para o Venda_Produtos e adicionar uma List.

Certo, obrigado !

Deu certo aqui, Abs.