Salvar em cascata com Fluent.

26 views
Skip to first unread message

Henrique Felipe

unread,
Apr 24, 2015, 8:57:17 AM4/24/15
to nhiber...@googlegroups.com
Bom dia pessoal,
Já tentei de várias formas, mas não estou conseguindo salvar 1..n.

Banco de dados: PostgreSQL

- Tabelas
CREATE TABLE venda
(
  id serial NOT NULL,
  data date,
  total numeric(15,2),
  desconto numeric(15,2),
  acrescimo numeric(15,2),
  clienteid bigint,
  situacao smallint,
  subtotal numeric(15,2),
  hora time without time zone NOT NULL DEFAULT now(),
  CONSTRAINT venda_pkey PRIMARY KEY (id ),
  CONSTRAINT venda_clienteid_fkey FOREIGN KEY (clienteid)  REFERENCES cliente (id) MATCH SIMPLE      ON UPDATE NO ACTION ON DELETE NO ACTION
)


CREATE TABLE vendaitem
(
  id serial NOT NULL,
  vendaid bigint NOT NULL,
  produtoid bigint,
  qtde numeric(5,2),
  valor numeric(15,2),
  CONSTRAINT vendaitem_pkey PRIMARY KEY (id ),
  CONSTRAINT vendaitem_produtoid_fkey FOREIGN KEY (produtoid)      REFERENCES produto (id) MATCH SIMPLE      ON UPDATE NO ACTION ON DELETE NO ACTION,
  CONSTRAINT vendaitem_vendaid_fkey FOREIGN KEY (vendaid)      REFERENCES venda (id) MATCH SIMPLE      ON UPDATE NO ACTION ON DELETE NO ACTION
)

- Classes

public class Venda
{
     public virtual long ID { get; set; }
     ......
      public virtual IList<VendaItem> VendaItem { get; set; }
}

public class VendaItem
{    
        public virtual long ID { get; set; }
        
        public virtual long VendaID { get; set; }
        public virtual long ProdutoID { get; set; }        

        public virtual decimal Qtde { get; set; }
        public virtual decimal Valor { get; set; }

        public virtual Venda Venda { get; set; }
        public virtual Produto Produto { get; set; }
 } 

- Mapeamentos

public class VendaMap : ClassMap<Venda>
    {
        public VendaMap()
        {
            Id(x => x.ID);
            Map(x => x.ClienteID);
            Map(x => x.Hora);
            Map(x => x.Data);
            Map(x => x.SubTotal);
            Map(x => x.Total);
            Map(x => x.Desconto);
            Map(x => x.Acrescimo);
            Map(x => x.Situacao);
            References(x => x.Cliente).Column("clienteid").ReadOnly().Not.LazyLoad();
            HasMany(x => x.VendaItem).Cascade.AllDeleteOrphan().KeyColumn("id");
            
            Table("venda");
        }
    }

public class VendaItemMap : ClassMap<VendaItem>
    {
        public VendaItemMap()
        {
            Id(x => x.ID);
            //Map(x => x.VendaID);
            Map(x => x.ProdutoID);
            Map(x => x.Qtde);
            Map(x => x.Valor);
            References(x => x.Venda).Column("vendaid");
            
            References(x => x.Produto).Column("produtoid").ReadOnly().Not.LazyLoad();
            Table("vendaitem");
        }
    }


Está dando o seguinte erro :

{"ERRO: 23502: valor nulo na coluna \"vendaid\" viola a restrição não-nula"}

Edno Silva

unread,
Apr 24, 2015, 9:48:42 AM4/24/15
to nhiber...@googlegroups.com
Vc tem 3 problemas aqui:

1) HasMany(x => x.VendaItem).Cascade.AllDeleteOrphan().KeyColumn("id") deveria ser HasMany(x => x.VendaItem).Cascade.AllDeleteOrphan().KeyColumn("vendaid")

(Em KeyColumn vc coloca o nome da chave estrangeira da tabela filha (vendaitem) para a tabela pai (venda))

2) Faltou usar Not.Inverse().Not.KeyNullable().Not.KeyUpdate() no HasMany;

3) Faltou um Inverse() no References(x => x.Venda).Column("vendaid");

Resumindo, fica assim:


VendaMap:
HasMany(x => x.VendaItem).Cascade.AllDeleteOrphan().KeyColumn("vendaid").Not.Inverse().Not.KeyNullable().Not.KeyUpdate();

VendaItemMap:
References(x => x.Venda).Column("vendaid").Inverse();

Outra coisa, verifique se você realmente precisa que VendaItem conheça Venda, é mais fácil trabalhar com relacionamentos unidirecionais...

--
Você recebeu essa mensagem porque está inscrito no grupo "NHibernate-Br" dos Grupos do Google.
Para cancelar inscrição nesse grupo e parar de receber e-mails dele, envie um e-mail para nhibernate-b...@googlegroups.com.
Para postar nesse grupo, envie um e-mail para nhiber...@googlegroups.com.
Acesse esse grupo em http://groups.google.com/group/nhibernate-br.
Para mais opções, acesse https://groups.google.com/d/optout.



--
Sem mais,
Edno.

Henrique Felipe

unread,
Apr 24, 2015, 10:01:34 AM4/24/15
to NHibernate-Br
obrigado pela  a resposta.
como seria o relacionamento unidirecionais ? 

seria assim:

salvar a venda e depois salvar a lista de vendaitem
-- 
Henrique Felipe
Analista de Sistemas 

"Inovação vem de pessoas que se divertem com seus trabalhos"

Edno Silva

unread,
Apr 24, 2015, 11:40:21 AM4/24/15
to nhiber...@googlegroups.com
Há duas formas de ficar unidirecional. A forma que eu recomendo é tirar a propriedade Venda da classe VendaItem. Desse jeito, basta salvar a Venda, pois o cascade cuida de tudo.

A outra forma é retirando a propriedade VendaItem da classe Venda. Neste caso não haverá cascade, e vc precisará salvar tanto a Venda quanto cada VendaItem.

Henrique Felipe

unread,
Apr 24, 2015, 11:41:56 AM4/24/15
to NHibernate-Br
ok, obrigado.
Assim que eu chegar em casa vou dá uma olhada.

valeu.

Henrique Felipe

unread,
Apr 24, 2015, 7:55:37 PM4/24/15
to NHibernate-Br
Deu certo retirando a propriedade Venda da classe VendaItem

Referente ao código debaixo, não existe esse metodo Inverse(). Pode ser que eu esteja usando uma versão mais velha que a sua

References(x => x.Venda).Column("vendaid").Inverse();


Em 24 de abril de 2015 10:48, Edno Silva <edno...@gmail.com> escreveu:



--

Edno Silva

unread,
Apr 25, 2015, 1:31:30 PM4/25/15
to nhiber...@googlegroups.com
O melhor caso é trabalhar com unidirecional mesmo.
Reply all
Reply to author
Forward
0 new messages