Solucionado (ver solução)

Importante

Você está vendo a versão anterior da nova experiência da Alura que estamos preparando para você. Em breve, ela ganha uma identidade visual novinha totalmente pensada em potencializar seus estudos!

Solucionado
(ver solução)
26
respostas

Relacionamento NHIBERNATE

Não estou conseguindo implementar os relacionamentos no banco de dados diretamente da aplicação usando NHibernate, estou com o seguinte erro abaixo:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace SistemaOCW.Entidade
{
    public class Empresa
    {
        public virtual int Id { get; set; }
        public virtual string Nome { get; set; }
        public virtual string Cnpj { get; set; }
        public virtual string Endereco { get; set; }
        public virtual string Bairro { get; set; }
        public virtual string Cidade { get; set; }
        public virtual string Cep { get; set; }
        public virtual string Telefone { get; set; }
        public virtual string Email { get; set; }
        public virtual string Contato { get; set; }
        public virtual IList<Cliente> Clientes { get; set; }

    }
}
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
                   assembly="SistemaOCW"
                   namespace="SistemaOCW.Entidade">
  <class name ="Empresa">
    <id name ="Id">
      <generator class ="identity"/>
    </id>
    <property name="Nome"/>
    <property name="Cnpj"/>
    <property name="Endereco"/>
    <property name="Bairro"/>
    <property name="Cidade"/>
    <property name="Cep"/>
    <property name="Telefone"/>
    <property name="Email"/>
    <property name="Contato"/> 
    <bag name="Clientes">
    <key column="EmpresaId"/>
    <one-to-many class="Cliente"/>
  </bag>
  </class>
</hibernate-mapping>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace SistemaOCW.Entidade
{
    public class Cliente
    {
        public virtual int Id { get; set; }
        public virtual int Codcliente { get; set; }
        public virtual string Nome { get; set; }
        public virtual string Cnpj { get; set; }
        public virtual string Endereco { get; set; }
        public virtual string Bairro { get; set; }
        public virtual string Cidade { get; set; }
        public virtual string Cep { get; set; }
        public virtual string Telefone { get; set; }
        public virtual string Email { get; set; }
        public virtual string Contato { get; set; }
        public virtual Empresa Empresa { get; set; }
    }
}
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
                   assembly="SistemaOCW"
                   namespace="SistemaOCW.Entidade">
  <class name ="Cliente">
    <id name ="Id">
      <generator class ="identity"/>
    </id>
    <property name="Codcliente"/>
    <property name="Nome"/>
    <property name="Cnpj"/>
    <property name="Endereco"/>
    <property name="Bairro"/>
    <property name="Cidade"/>
    <property name="Cep"/>
    <property name="Telefone"/>
    <property name="Email"/>
    <property name="Contato"/>
  <many-to-one name="Empresa" column="EmpresaId"/>
     </class>
</hibernate-mapping>
NHibernate.Exceptions.GenericADOException não foi manipulada pelo código do usuário
  HResult=-2146232832
  Message=could not insert: [SistemaOCW.Entidade.Cliente][SQL: INSERT INTO Cliente (Codcliente, Nome, Cnpj, Endereco, Bairro, Cidade, Cep, Telefone, Email, Contato, EmpresaId) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)]
  Source=NHibernate
  SqlString=INSERT INTO Cliente (Codcliente, Nome, Cnpj, Endereco, Bairro, Cidade, Cep, Telefone, Email, Contato, EmpresaId) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
  StackTrace:
       em NHibernate.Id.Insert.AbstractSelectingDelegate.PerformInsert(SqlCommandInfo insertSQL, ISessionImplementor session, IBinder binder)
       em NHibernate.Persister.Entity.AbstractEntityPersister.Insert(Object[] fields, Boolean[] notNull, SqlCommandInfo sql, Object obj, ISessionImplementor session)
       em NHibernate.Persister.Entity.AbstractEntityPersister.Insert(Object[] fields, Object obj, ISessionImplementor session)
       em NHibernate.Action.EntityIdentityInsertAction.Execute()
       em NHibernate.Engine.ActionQueue.Execute(IExecutable executable)
       em NHibernate.Event.Default.AbstractSaveEventListener.PerformSaveOrReplicate(Object entity, EntityKey key, IEntityPersister persister, Boolean useIdentityColumn, Object anything, IEventSource source, Boolean requiresImmediateIdAccess)
       em NHibernate.Event.Default.AbstractSaveEventListener.PerformSave(Object entity, Object id, IEntityPersister persister, Boolean useIdentityColumn, Object anything, IEventSource source, Boolean requiresImmediateIdAccess)
       em NHibernate.Event.Default.AbstractSaveEventListener.SaveWithGeneratedId(Object entity, String entityName, Object anything, IEventSource source, Boolean requiresImmediateIdAccess)
       em NHibernate.Event.Default.DefaultSaveOrUpdateEventListener.SaveWithGeneratedOrRequestedId(SaveOrUpdateEvent event)
       em NHibernate.Event.Default.DefaultSaveOrUpdateEventListener.EntityIsTransient(SaveOrUpdateEvent event)
       em NHibernate.Event.Default.DefaultSaveEventListener.PerformSaveOrUpdate(SaveOrUpdateEvent event)
       em NHibernate.Event.Default.DefaultSaveOrUpdateEventListener.OnSaveOrUpdate(SaveOrUpdateEvent event)
       em NHibernate.Impl.SessionImpl.FireSave(SaveOrUpdateEvent event)
       em NHibernate.Impl.SessionImpl.Save(Object obj)
       em SistemaOCW.DAO.ClienteDAO.Adiciona(Cliente cliente) na d:\OCW\SistemaOCW\SistemaOCW\DAO\ClienteDAO.cs:linha 26
       em SistemaOCW.Controllers.ClienteController.Adiciona(Cliente cliente) na d:\OCW\SistemaOCW\SistemaOCW\Controllers\ClienteController.cs:linha 34
       em lambda_method(Closure , ControllerBase , Object[] )
       em System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters)
       em System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters)
       em System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters)
       em System.Web.Mvc.ControllerActionInvoker.<>c__DisplayClass15.<InvokeActionMethodWithFilters>b__12()
       em System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func`1 continuation)
  InnerException: MySql.Data.MySqlClient.MySqlException
       HResult=-2147467259
       Message=Cannot add or update a child row: a foreign key constraint fails (`compras`.`cliente`, CONSTRAINT `FKE156C0F996677116` FOREIGN KEY (`Id`) REFERENCES `empresa` (`Id`))
       Source=MySql.Data
       ErrorCode=-2147467259
       Number=1452
       StackTrace:
            em MySql.Data.MySqlClient.MySqlStream.ReadPacket()
            em MySql.Data.MySqlClient.NativeDriver.GetResult(Int32& affectedRow, Int64& insertedId)
            em MySql.Data.MySqlClient.Driver.GetResult(Int32 statementId, Int32& affectedRows, Int64& insertedId)
            em MySql.Data.MySqlClient.Driver.NextResult(Int32 statementId, Boolean force)
            em MySql.Data.MySqlClient.MySqlDataReader.NextResult()
            em MySql.Data.MySqlClient.MySqlCommand.ExecuteReader(CommandBehavior behavior)
            em MySql.Data.MySqlClient.MySqlCommand.ExecuteReader()
            em MySql.Data.MySqlClient.MySqlCommand.ExecuteNonQuery()
            em NHibernate.AdoNet.AbstractBatcher.ExecuteNonQuery(IDbCommand cmd)
            em NHibernate.Id.Insert.AbstractSelectingDelegate.PerformInsert(SqlCommandInfo insertSQL, ISessionImplementor session, IBinder binder)
       InnerException: 
enter code here
26 respostas

Acrescentei na Bag "inverse = true"

Começou a gravar o cliente nao gerou exeption, fui no MySQl e coloquei a selet abaixo:

select empresa.Id, empresa.nome,  cliente.Id, cliente.Nome
from  cliente, empresa
where empresa.Id = cliente.Id

ele me traz uma empresa de Id 1 com um cliente de Id 1 uma empresa de Id2 com cliente de Id 2 uma empresa de Id3 com cliente de Id 3 depois parou de inserir o cliente e voltou o erro acima na session.save() esse relacionamento também esta errado, ele deveria me trazer uma empresa com varios clientes, e varios cliente somente de uma empresa.

Olá Leonardo,

Vamos começar pela query feita por você, vocês está dizendo na query que quer registros da tabela cliente onde o ID da empresa seja igual ao id do cliente. Pelo que entendi pelo seus arquivos hbm, a rotina deveria ser assim:

select empresa.Id, empresa.nome,  cliente.Id, cliente.Nome
from  cliente, empresa
where empresa.Id = cliente.EmpresaId

Pois o que você se confundiu, foi que na tabela empresa o nome do campo do campo é Id e na tabela de clientesó campo com código da empresa é EmpresaID.

Quanto ao erro, me parece ser em outra parte da aplicação, porém relacionado ao mesmo tipo de erro, pois está dizendo o seguinte:

Cannot add or update a child row: a foreign key constraint fails (compras.cliente, CONSTRAINT FKE156C0F996677116 FOREIGN KEY (Id) REFERENCES empresa (Id))

Ao que me parece, está tentando colocar um código de cliente em um campo ID que referencia a tabela empresa. Me corrijam se eu estiver errado.

Só corrigindo o erro de digitação segue a frase que saiu tudo trocado, rs:

Pois o que você se confundiu, foi que na tabela empresa, o nome do campo chave é Id e na tabela cliente, o campo com código da empresa é EmpresaID

.

Rafael; Eu tenho uma empresa cadastrada e quero pegar todos os clientes daquela empresa. Quando faço a consulta no banco de dados (select * from cliente) ele esta me trazendo todos os clientes, só que o campo EmpresaId que deveria guardar a chave da empresa o valor 1 esta null.

realizando a sua consulta que esta certa

select empresa.Id, empresa.nome,  cliente.Id, cliente.Nome
from  cliente, empresa
where empresa.Id = cliente.EmpresaId

ele nao traz nada porque o empresaid nao tabela clienre esta null.

O inverse=true, foi acrescentado após você inserir estes clientes? Pois, talvez você tenha alterado a empresa e aí o merge foi feito e tirado o relacionamento dos clientes com a empresa. Neste caso, eu faria:

update empresa   
set empresaId = 1 
where empresaId is null

E aí observaria a partir disso, incluindo clientes testes e alterando a Empresa. Porque tenho quase certeza que foi o merge que fez isso antes de você colocar "inverse = true".

ops corrigindo.

update Cliente
set empresaId = 1 
where empresaId is null

Realizei esse comando no banco, ele seta os valores nos clientes ja cadastrado, quando cadastro um novo cliente volta a vir valor null. acho que o erro esta vindo da aplicação daquela configuração nas classes de mapeamentos.

Essas modificações nas classes de mapeamento eu fiz depois de ter o banco junto com as tabelas o banco, o relacionamento.

Leonardo, Deixamos passar em branco um detalhe, faltou informar a classe Empresa na tag:

<many-to-one name="Empresa" column="EmpresaId" class="Empresa" />

Agora vai!

Rafael fiz a modificação e nao deu certo, continua vindo o cliente que cadastro com o empresaid null

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
                   assembly="SistemaOCW"
                   namespace="SistemaOCW.Entidade">
  <class name ="Cliente">
    <id name ="Id">
      <generator class ="identity"/>
    </id>
    <property name="Codcliente"/>
    <property name="Nome"/>
    <property name="Cnpj"/>
    <property name="Endereco"/>
    <property name="Bairro"/>
    <property name="Cidade"/>
    <property name="Cep"/>
    <property name="Telefone"/>
    <property name="Email"/>
    <property name="Contato"/>
    <many-to-one name="Empresa" column="EmpresaId" class = "Empresa"/>
     </class>
</hibernate-mapping>
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
                   assembly="SistemaOCW"
                   namespace="SistemaOCW.Entidade">
  <class name ="Empresa">
    <id name ="Id">
      <generator class ="identity"/>
    </id>
    <property name="Nome"/>
    <property name="Cnpj"/>
    <property name="Endereco"/>
    <property name="Bairro"/>
    <property name="Cidade"/>
    <property name="Cep"/>
    <property name="Telefone"/>
    <property name="Email"/>
    <property name="Contato"/> 
    <bag name="Clientes" inverse="true">
    <key column="EmpresaId"/>
    <many-to-one class="Cliente"/>
  </bag>
  </class>
</hibernate-mapping>

Vc pode colocar aqui o método adiciona da cliente dao e a action da controller?

using NHibernate;
using SistemaOCW.DAO;
using SistemaOCW.Entidade;
using SistemaOCW.Infra;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;


namespace SistemaOCW.Controllers
{
    public class ClienteController : Controller
    {  

           public ActionResult Form()
        {
            return View();
        }
        //
        // GET: /Cliente/

        public ActionResult Index()
        {
            return View();
        }

        public ActionResult Adiciona(Cliente cliente)
        {

            ISession session = NHibernateHelper.AbreSession();
            ClienteDAO dao = new ClienteDAO(session);       

            dao.Adiciona(cliente);
            session.Close();
            return RedirectToAction("Index");
        }

    }
}
using SistemaOCW.Entidade;
using System;
using System.Collections.Generic;
using System.EnterpriseServices;
using System.Linq;
using System.Web;
using SistemaOCW.Infra;
using NHibernate;

namespace SistemaOCW.DAO
{
    public class ClienteDAO
    {
        private ISession session;


        public ClienteDAO(ISession session)
        {
            this.session = session;
        }


        public void Adiciona(Cliente cliente)
        {
            NHibernate.ITransaction transacao = session.BeginTransaction();
            session.Save(cliente);
            transacao.Commit();
        }


        // public Cliente BuscaPorId(int id)
        //  {
        //  return session.Get<Cliente>(id);
        //  }
    }
}

Blz. Você pode colocar aqui a view do form que cadastra o cliente, esqueci pedir.

@{
    ViewBag.Title = "Form";
}

<h2>Cadastro Cliente</h2>

<form action="@Url.Action("Adiciona", "Cliente")" method="post">
    <label>
        Codigo:
        <input type="text" name="cliente.Codcliente" />
        Nome:
        <input type="text" name="cliente.Nome" />
         CNPJ:
        <input type="text" name="cliente.Cnpj" />
         Endereco:
        <input type="text" name="cliente.Endereco" />
         Bairro:
        <input type="text" name="cliente.Bairro" />
         Cidade:
        <input type="text" name="cliente.Cidade" />
         CEP:
        <input type="text" name="cliente.Cep" />
         Telefone:
        <input type="text" name="cliente.Telefone" />
         Email:
        <input type="text" name="cliente.Email" />
         Contato:
        <input type="text" name="cliente.Contato" />

    </label>
    <input type="submit" value="Adicionar"/>
</form>

Oi Leonardo

Parece que a tabela de clientes do seu banco de dados foi criada incorretamente.

Você poderia executar os comandos abaixo no mysql e depois postar o resultado?

Primeiro comando:

show create table Empresa;

e o segundo comando:

show create table Cliente;
CREATE TABLE `empresa` (
   `Id` int(11) NOT NULL AUTO_INCREMENT,
   `Nome` varchar(255) DEFAULT NULL,
   `Cnpj` varchar(255) DEFAULT NULL,
   `Endereco` varchar(255) DEFAULT NULL,
   `Bairro` varchar(255) DEFAULT NULL,
   `Cidade` varchar(255) DEFAULT NULL,
   `Cep` varchar(255) DEFAULT NULL,
   `Telefone` varchar(255) DEFAULT NULL,
   `Email` varchar(255) DEFAULT NULL,
   `Contato` varchar(255) DEFAULT NULL,
   PRIMARY KEY (`Id`)
 ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8
CREATE TABLE `cliente` (
   `Id` int(11) NOT NULL AUTO_INCREMENT,
   `Codcliente` int(11) DEFAULT NULL,
   `Nome` varchar(255) DEFAULT NULL,
   `Cnpj` varchar(255) DEFAULT NULL,
   `Endereco` varchar(255) DEFAULT NULL,
   `Bairro` varchar(255) DEFAULT NULL,
   `Cidade` varchar(255) DEFAULT NULL,
   `Cep` varchar(255) DEFAULT NULL,
   `Telefone` varchar(255) DEFAULT NULL,
   `Email` varchar(255) DEFAULT NULL,
   `Contato` varchar(255) DEFAULT NULL,
   `EmpresaId` int(11) DEFAULT NULL,
   PRIMARY KEY (`Id`),
   KEY `EmpresaId` (`EmpresaId`),
   CONSTRAINT `FKE156C0F9105A37B` FOREIGN KEY (`EmpresaId`) REFERENCES `empresa` (`Id`)
 ) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8

Leonardo, onde você informa o ID da empresa no formulário de cadastro de clientes? Pelo que entendi o problema seria que todo cliente está com IdEmpresa nulo, mas no form não existe esta informação?

Rafael; Eu nao tenho um campo texto para preencher manual, no meu entendimento como vou ter so uma empresa cadastrada penso que o id da empresa iria ser automático para o cliente, nao sei se isso é possível, estou pesquisando na internet varia formas de fazer isso mas ainda nao achei a solução.

Rafael; Se acho que se fosse assim na linha do seu raciocinio eu poderia simplesmente comparar cod cliente com id da empresa, iria preencher todos os codcliente com id 1 e a empresa ja estaria com id 1. ai nao precisaria nem de chave estrangeira.

CONSTRAINT FKE156C0F9105A37B FOREIGN KEY (EmpresaId) REFERENCES empresa (Id) ou seja o Forg Key chama EMpresaID e não ID como ta no código do erro do Nhibernate

Paulo; Voce esta me dizendo que meu codgo tem que ficar assim:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
                   assembly="SistemaOCW"
                   namespace="SistemaOCW.Entidade">
  <class name ="Empresa">
    <id name ="EmpresaId">
      <generator class ="identity"/>
    </id>
    <property name="Nome"/>
    <property name="Cnpj"/>
    <property name="Endereco"/>
    <property name="Bairro"/>
    <property name="Cidade"/>
    <property name="Cep"/>
    <property name="Telefone"/>
    <property name="Email"/>
    <property name="Contato"/>
    <bag name="Clientes">
      <key column="EmpresaId"/>
      <one-to-many class="Cliente"/>
    </bag>
  </class>
</hibernate-mapping>
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
                   assembly="SistemaOCW"
                   namespace="SistemaOCW.Entidade">
  <class name ="Cliente">
    <id name ="Id">
      <generator class ="identity"/>
    </id>
    <property name="Codcliente"/>
    <property name="Nome"/>
    <property name="Cnpj"/>
    <property name="Endereco"/>
    <property name="Bairro"/>
    <property name="Cidade"/>
    <property name="Cep"/>
    <property name="Telefone"/>
    <property name="Email"/>
    <property name="Contato"/>
    <many-to-one name="Empresa" column="EmpresaId" class = "Empresa"/>
  </class>
</hibernate-mapping>

Mudei todo o codigo para ver se dava certo, e deu outro erro.

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
                   assembly="SistemaOCW"
                   namespace="SistemaOCW.Entidade">
  <class name ="Empresa">
    <id name ="Id">
    <generator class ="identity"/>
    </id>
    <property name="Nome"/>
    <property name="Cnpj"/>
    <property name="Endereco"/>
    <property name="Bairro"/>
    <property name="Cidade"/>
    <property name="Cep"/>
    <property name="Telefone"/>
    <property name="Email"/>
    <property name="Contato"/> 
    <bag name="Clientes">
    <key column= "Id"/>
    <one-to-many class="Cliente"/>  
      </bag>
  </class>
</hibernate-mapping>
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
                   assembly="SistemaOCW"
                   namespace="SistemaOCW.Entidade">
  <class name ="Cliente">
    <id name ="Id">
      <generator class ="identity"/>
    </id>
    <property name="Codcliente"/>
    <property name="Nome"/>
    <property name="Cnpj"/>
    <property name="Endereco"/>
    <property name="Bairro"/>
    <property name="Cidade"/>
    <property name="Cep"/>
    <property name="Telefone"/>
    <property name="Email"/>
    <property name="Contato"/>
    <many-to-one name="empresa" column="Id" class = "Empresa"/>
  </class>
</hibernate-mapping>

Inseri uma empresa, depois inseri um cliente, olhei no banco nao deu certo, fui inserir um segundo cliente deu esse erro:

NHibernate.Exceptions.GenericADOException não foi manipulada pelo código do usuário
  HResult=-2146232832
  Message=could not insert: [SistemaOCW.Entidade.Cliente][SQL: INSERT INTO Cliente (Codcliente, Nome, Cnpj, Endereco, Bairro, Cidade, Cep, Telefone, Email, Contato, Id) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)]
  Source=NHibernate
  SqlString=INSERT INTO Cliente (Codcliente, Nome, Cnpj, Endereco, Bairro, Cidade, Cep, Telefone, Email, Contato, Id) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
  StackTrace:
       em NHibernate.Id.Insert.AbstractSelectingDelegate.PerformInsert(SqlCommandInfo insertSQL, ISessionImplementor session, IBinder binder)
       em NHibernate.Persister.Entity.AbstractEntityPersister.Insert(Object[] fields, Boolean[] notNull, SqlCommandInfo sql, Object obj, ISessionImplementor session)
       em NHibernate.Persister.Entity.AbstractEntityPersister.Insert(Object[] fields, Object obj, ISessionImplementor session)
       em NHibernate.Action.EntityIdentityInsertAction.Execute()
       em NHibernate.Engine.ActionQueue.Execute(IExecutable executable)
       em NHibernate.Event.Default.AbstractSaveEventListener.PerformSaveOrReplicate(Object entity, EntityKey key, IEntityPersister persister, Boolean useIdentityColumn, Object anything, IEventSource source, Boolean requiresImmediateIdAccess)
       em NHibernate.Event.Default.AbstractSaveEventListener.PerformSave(Object entity, Object id, IEntityPersister persister, Boolean useIdentityColumn, Object anything, IEventSource source, Boolean requiresImmediateIdAccess)
       em NHibernate.Event.Default.AbstractSaveEventListener.SaveWithGeneratedId(Object entity, String entityName, Object anything, IEventSource source, Boolean requiresImmediateIdAccess)
       em NHibernate.Event.Default.DefaultSaveOrUpdateEventListener.SaveWithGeneratedOrRequestedId(SaveOrUpdateEvent event)
       em NHibernate.Event.Default.DefaultSaveOrUpdateEventListener.EntityIsTransient(SaveOrUpdateEvent event)
       em NHibernate.Event.Default.DefaultSaveEventListener.PerformSaveOrUpdate(SaveOrUpdateEvent event)
       em NHibernate.Event.Default.DefaultSaveOrUpdateEventListener.OnSaveOrUpdate(SaveOrUpdateEvent event)
       em NHibernate.Impl.SessionImpl.FireSave(SaveOrUpdateEvent event)
       em NHibernate.Impl.SessionImpl.Save(Object obj)
       em SistemaOCW.DAO.ClienteDAO.Adiciona(Cliente cliente) na d:\OCW\SistemaOCW\SistemaOCW\DAO\ClienteDAO.cs:linha 26
       em SistemaOCW.Controllers.ClienteController.Adiciona(Cliente cliente) na d:\OCW\SistemaOCW\SistemaOCW\Controllers\ClienteController.cs:linha 35
       em lambda_method(Closure , ControllerBase , Object[] )
       em System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters)
       em System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters)
       em System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters)
       em System.Web.Mvc.ControllerActionInvoker.<>c__DisplayClass15.<InvokeActionMethodWithFilters>b__12()
       em System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func`1 continuation)
  InnerException: MySql.Data.MySqlClient.MySqlException
       HResult=-2147467259
       Message=Cannot add or update a child row: a foreign key constraint fails (`compras`.`cliente`, CONSTRAINT `FKE156C0F996677116` FOREIGN KEY (`Id`) REFERENCES `empresa` (`Id`))
       Source=MySql.Data
       ErrorCode=-2147467259
       Number=1452
       StackTrace:
            em MySql.Data.MySqlClient.MySqlStream.ReadPacket()
            em MySql.Data.MySqlClient.NativeDriver.GetResult(Int32& affectedRow, Int64& insertedId)
            em MySql.Data.MySqlClient.Driver.GetResult(Int32 statementId, Int32& affectedRows, Int64& insertedId)
            em MySql.Data.MySqlClient.Driver.NextResult(Int32 statementId, Boolean force)
            em MySql.Data.MySqlClient.MySqlDataReader.NextResult()
            em MySql.Data.MySqlClient.MySqlCommand.ExecuteReader(CommandBehavior behavior)
            em MySql.Data.MySqlClient.MySqlCommand.ExecuteReader()
            em MySql.Data.MySqlClient.MySqlCommand.ExecuteNonQuery()
            em NHibernate.AdoNet.AbstractBatcher.ExecuteNonQuery(IDbCommand cmd)
            em NHibernate.Id.Insert.AbstractSelectingDelegate.PerformInsert(SqlCommandInfo insertSQL, ISessionImplementor session, IBinder binder)
       InnerException:

Voltei olhei no banco, ele cria duas fk

Cliente    CREATE TABLE `cliente` (
  `Id` int(11) NOT NULL AUTO_INCREMENT,
  `Codcliente` int(11) DEFAULT NULL,
  `Nome` varchar(255) DEFAULT NULL,
  `Cnpj` varchar(255) DEFAULT NULL,
  `Endereco` varchar(255) DEFAULT NULL,
  `Bairro` varchar(255) DEFAULT NULL,
  `Cidade` varchar(255) DEFAULT NULL,
  `Cep` varchar(255) DEFAULT NULL,
  `Telefone` varchar(255) DEFAULT NULL,
  `Email` varchar(255) DEFAULT NULL,
  `Contato` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`Id`),
  KEY `Id` (`Id`),
  KEY `Id_2` (`Id`),
  CONSTRAINT `FKE156C0F996677116` FOREIGN KEY (`Id`) REFERENCES `empresa` (`Id`),
  CONSTRAINT `FKE156C0F9CEE14BB0` FOREIGN KEY (`Id`) REFERENCES `empresa` (`Id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8
Empresa    CREATE TABLE `empresa` (
  `Id` int(11) NOT NULL AUTO_INCREMENT,
  `Nome` varchar(255) DEFAULT NULL,
  `Cnpj` varchar(255) DEFAULT NULL,
  `Endereco` varchar(255) DEFAULT NULL,
  `Bairro` varchar(255) DEFAULT NULL,
  `Cidade` varchar(255) DEFAULT NULL,
  `Cep` varchar(255) DEFAULT NULL,
  `Telefone` varchar(255) DEFAULT NULL,
  `Email` varchar(255) DEFAULT NULL,
  `Contato` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`Id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8

Oi Leonardo

O problema desse novo mapeamento é que agora você está falando para o NHibernate utilizar a coluna Id da tabela de clientes tanto como chave primária quanto chave estrangeira para a Empresa, dessa forma, só é possível inserir um Cliente se já existir uma empresa com o mesmo Id desse novo cliente. Esse tipo de mapeamento só é utilizado em situações muito específicas (em caso de herança, por exemplo).

O correto seria:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
                   assembly="SistemaOCW"
                   namespace="SistemaOCW.Entidade">
  <class name ="Empresa">
    <id name ="Id">
    <generator class ="identity"/>
    </id>
    <property name="Nome"/>
    <property name="Cnpj"/>
    <property name="Endereco"/>
    <property name="Bairro"/>
    <property name="Cidade"/>
    <property name="Cep"/>
    <property name="Telefone"/>
    <property name="Email"/>
    <property name="Contato"/> 
    <bag name="Clientes">
      <key column= "EmpresaId"/>
      <one-to-many class="Cliente"/>  
    </bag>
  </class>
</hibernate-mapping>
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
                   assembly="SistemaOCW"
                   namespace="SistemaOCW.Entidade">
  <class name ="Cliente">
    <id name ="Id">
      <generator class ="identity"/>
    </id>
    <property name="Codcliente"/>
    <property name="Nome"/>
    <property name="Cnpj"/>
    <property name="Endereco"/>
    <property name="Bairro"/>
    <property name="Cidade"/>
    <property name="Cep"/>
    <property name="Telefone"/>
    <property name="Email"/>
    <property name="Contato"/>
    <many-to-one name="empresa" column="EmpresaId" class = "Empresa"/>
  </class>
</hibernate-mapping>

Antes de testar esse mapeamento, execute um drop table para remover as tabelas Cliente e Empresa do seu banco de dados para que as foreign keys que foram criadas sejam descartadas.

Sim Victor refiz os passos que você pediu, esta gravando a empresa, esta gravando o cliente, quero saber se com isso ele teria qu preencher automaticamente o empresaid no cliente, para quando eu executar essa consulta abaixo já trazer todos os clientes daquela empresa.

select empresa.Id, empresa.nome,  cliente.Id, cliente.Nome
from  cliente, empresa
where empresa.Id = cliente.EmpresaId

ou eu vou ter que criar um mais um campo e preencher ele manualmente com o id da empresa que quero que o cliente faça parte.

solução!

Você tem duas opções:

colocar um novo campo no seu formulário, mesmo que seja um campo hidden que já vem preenchido com o id correto da empresa

ou você poderia modificar o código da sua lógica que grava o cliente com o NHibernate para fazer com que ela preencha o id da empresa.