Bueno Guillermo, he estado mirando todo lo que me has pasado y leyendo
tu correo. Me has hecho cambiar de opinión, ya que a mí también me
parece mucho más coherente la idea de que EmailDA sea una entidad
débil cuya existencia depende de DatosPersonalesDA. Por tanto he
optado por hacer el mapeo con un composite-element como me indicaste.
Ya lo he probado y funciona a las mil maravillas, y conservando la
clave primaria compuesta, la cual quería conservar pues era una
restricción a mi modo de ver necesaria.

Esto me hace replantearme varias cosas respecto al mapeo actual que
tengo, ya que DatosPersonalesDA (como es de suponer) no sólo tiene
EmailDA, si no que también tiene teléfonos, direcciones, etc, por lo
que todas esas entidades (también débiles) deberían seguir un patrón
de mapeo similar.

Me miraré las opciones para el generator de las id de cada tabla
(aunque ya me las había mirado un poco por encima), e indagaré sobre
cuál es la que más me conviene.

Por último, muchísimas gracias por el tiempo que has invertido en
darme una contestación tan completa y tan bien argumentada. Te lo
agradezco muchísimo de veras, a ti y a todos los que habéis
participado en este post tratando de echarme una mano.

Saludos!

On 1 feb, 22:33, "Guillermo Ruffino" <[EMAIL PROTECTED]> wrote:
> Este deberia ser tu mapeo:
>
> <?xml version="1.0" encoding="utf-8" ?>
> <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
>   <class name="TestCon.Entities.DatosPersonalesDA, TestCon"
> table="DatosPersonales">
>     <id name="IdPersonales" column="idpersonales">
>       <generator class="assigned" />
>     </id>
>
>     <bag name="Emails" inverse="true">
>       <key foreign-key="idpersonales" column="idpersonales"/>
>       <one-to-many class="TestCon.Entities.EmailDA, TestCon" />
>     </bag>
>   </class>
>   <class name="TestCon.Entities.EmailDA, TestCon" table="email">
>     <composite-id>
>       <key-property name="IdPersonales" column="idpersonales"/>
>       <key-property name="Email" column="mail"/>
>     </composite-id>
>   </class>
> </hibernate-mapping>
>
> Ya que me interiorice bastante en el tema y le dedique bastante tiempo me
> voy a dedicar a indicar unas cosas: generator class = Assigned ??? supongo
> que puede llegar a ser útil si estas mapeando contra archivos de texto..
> investiga este tema que casi seguro existe una opción mejor (incluso si tus
> tablas no son identity)
>
> Este mapeo es lo mas parecido que me salió a lo que querías hacer andar,
> pero no te da mucha ventaja en el código, o sea, te queda EmailDA como una
> entidad, a mi gusto EmailDA seria un componente y viviría siempre que viva
> la tabla padre (DatosPersonales) se supone que una entidad puede vivir sin
> otra, y no es este el caso (no puede vivir Email sin Datos Personales en tu
> modelo relacional), lo que digo que esta mal es el mapeo, tener esas
> restricciones en el modelo relacional me parece buenísimo. (En esta estoy en
> contra con la mayoría del grupo ke van en contra de los composite id)
>
> Bueno en fin, yo mapearía mas bien con un composite-element, esto daría
> resultados muy similares, y haría que tu clase EmailDA sea "débil" de datos
> personales (si se me permite hablar de objetos débiles).
>
> El mapeo quedaría:
>
> <?xml version="1.0" encoding="utf-8" ?>
> <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
>   <class name="TestCon.Entities.DatosPersonalesDA, TestCon"
> table="DatosPersonales">
>     <id name="IdPersonales" column="idpersonales">
>       <generator class="assigned" />
>     </id>
>
>     <bag name="Emails" table="email">
>       <key column="idpersonales" />
>       <composite-element class="TestCon.Entities.EmailDA, TestCon">
>         <property name="Email" column="mail"/>
>       </composite-element>
>     </bag>
>   </class>
> </hibernate-mapping>
>
> Aglo interesante por notar aquí es que la herramienta hbm2sql con el primer
> hbm genera un modelo muy parecido a lo que vos tenes, digo, crea las claves
> compuestas en la tabla email.
> Este otro modelo crea ambas columnas pero no indica primary key, de todas
> formas yo te recomiendo que dejes las primary key y la foreign key en el
> modelo de la base de datos, nhibernate no va a saber ke esas restricciones
> están pero va a actuar como ke si están, los insert / deletes van a ser los
> adecuados.
>
> La operación de delete con este metdodo (cuando los EmailDA ya no son
> entidades) es mucho mas natural:
> DatosPersonales dp = sesión.Load<DatosPersonales>(4);
> Sesión.Delete(dp);
>
> Eso envía dos instrucciones sql:
> Delete from emails where idpersonales = 4;
> Delete from datospersonales where idpersonales = 4;
>
> Creo que es algo realmente optimo, borra si es que existen y sino no
> consideralo un no-op, lo interesante es que nhibernate no sabe si hay
> objetos (filas) que existan antes de eliminarlos.
>
> Voy a adjuntar el proyectito en .net aquí para que lo pruebes y decidas cual
> vas a cambiar.
>
> Saludos
>
> -----Original Message-----
> From: [email protected]
>
> [mailto:[EMAIL PROTECTED] On Behalf Of Chili
> Sent: Thursday, February 01, 2007 16:42
> To: NHibernate-Hispano
> Subject: [NHibernate-Hispano] Re: Problemas con un update
>
> >Con composite-id el saveorupdate no funciona.
>
> Y Update a secas? Ya lo he probado y el error es el mismo.
>
> > debes tener el campo idpersonales not null en la tabla y lo estas mandando
> null
>
> No puedo permitir null porque forma parte de una composite-id.
>
> Andrés te voy a plantear el problema a ver si me puedes hechar un
> cable en el modelado de datos.
> Tengo una tabla DatosPersonales. Uno de los campos que pueden tener
> los datos personales son emails. Puede tener 0, 1 o muchos. La tabla
> Email tiene una clave foránea a DatosPersonales, que es la famosa
> idpersonales, y otro campo de texto con el email. Si la clave primaria
> sólo fuese idpersonales, cada persona sólo podría tener un email, y si
> la clave fuese el email, dos usuarios no podrían compartir un email
> (esto no es tan descabellado, pero es una restricción que puede
> necesitar ser violada. Piensen en un email de un laboratorio, una
> organización, etc).
>
> Los demás también pueden hacer sus sugerencias. Gracias por todo!
>
> On 1 feb, 20:15, "Ezequiel Jadib" <[EMAIL PROTECTED]> wrote:
> > debes tener el campo idpersonales not null en la tabla y lo estas mandando
> null
>
> ----------------------------------------------------------------------------
> ----
>
> > rdi2k | Ezequiel Jadib | MSN: [EMAIL PROTECTED] |
> Blogs:http://geeks.ms/blogs/ejadib/(ES) - ejadib.wordpress.com (EN)
>
> >   ----- Original Message -----
> >   From: Dario Quintana
> >   To: [email protected]
> >   Sent: Thursday, February 01, 2007 4:11 PM
> >   Subject: [NHibernate-Hispano] Re: Problemas con un update
>
> >   Con composite-id el saveorupdate no funciona.
>
> >   On 2/1/07, Chili <[EMAIL PROTECTED]> wrote:
>
> >   > Bien, parece que tengo más problemas. Una vez asumido que tenía que
> >   > hacer un delete del email antes de hacer el SaveOrUpdate de la clase
> >   > padre, me encuentro con que no he avanzado nada y sigo donde estaba,
> >   > esto es, con el mismo error.
>
> >   > Hago el delete satisfactoriamente, me borra la fila de la tabla
> >   > correspondiente de la base de datos, pero en el momento que intento
> >   > actualizar el member (clase padre), el error que salta es el mismo.
>
> >   > Por si alguien no lo recordaba:
>
> >   >  Cannot insert the value NULL into column 'idpersonales', table
> >   > 'curriculum.dbo.email'; column does not allow nulls. UPDATE fails.
> >   > The statement has been terminated.
> >   > Description: An unhandled exception occurred during the execution of
> >   > the current web request. Please review the stack trace for more
> >   > information about the error and where it originated in the code.
>
> >   > Exception Details: System.Data.SqlClient.SqlException: Cannot insert
> >   > the value NULL into column 'idpersonales', table
> >   > 'curriculum.dbo.email'; column does not allow nulls. UPDATE fails.
> >   > The statement has been terminated.
> >   > Stack Trace:
>
> >   > [SqlException (0x80131904): Cannot insert the value NULL into column
> >   > 'idpersonales', table 'curriculum.dbo.email'; column does not allow
> >   > nulls. UPDATE fails.
> >   > The statement has been terminated.]
> >   >    System.Data.SqlClient.SqlConnection.OnError(SqlException exception,
> >   > Boolean breakConnection) +95
> >   >    System.Data.SqlClient.SqlInternalConnection.OnError(SqlException
> >   > exception, Boolean breakConnection) +82
>
> System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObjec
> t
> >   > stateObj) +346
> >   >    System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior,
> >   > SqlCommand cmdHandler, SqlDataReader dataStream,
> >   > BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject
> >   > stateObj) +3244
> >   >    System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader
> >   > ds, RunBehavior runBehavior, String resetOptionsString) +186
>
> >   > System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior
> >   > cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean
> >   > async) +1121
> >   >    System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior
> >   > cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String
> >   > method, DbAsyncResult result) +334
>
> >   > System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(DbAsyncResult
> >   > result, String methodName, Boolean sendToPipe) +407
> >   >    System.Data.SqlClient.SqlCommand.ExecuteNonQuery() +149
> >   >    NHibernate.Impl.BatcherImpl.ExecuteNonQuery(IDbCommand cmd) in c:
> >   > \net\nhibernate-1.2.0.Beta1\nhibernate\src\NHibernate\Impl
> >   > \BatcherImpl.cs:172
>
> NHibernate.Persister.Collection.AbstractCollectionPersister.DeleteRows(IPers
> istentCollection
> >   > collection, Object id, ISessionImplementor session) in c:\net
> >   > \nhibernate-1.2.0.Beta1\nhibernate\src\NHibernate\Persister\Collection
> >   > \AbstractCollectionPersister.cs:947
>
> >   > [ADOException: could not delete collection rows:
> >   > [dataAccess.csfiles.datospersonalesygrupo.DatosPersonalesDA.Emails#1]]
> >   >    dataAccess.csfiles.DBManager.saveMember(MemberDA member) in C:
> >   > \Documents and Settings\César Díaz García\Mis documentos\Visual Studio
> >   > 2005\Projects\dataAccess\dataAccess\DBManager.cs:97
> >   >    Controlador.saveMember(MemberDA member) in c:\Documents and
> Settings
> >   > \César Díaz García\Mis documentos\Visual Studio 2005\WebSites\proyecto
> >   > \App_Code\Controlador.cs:58
> >   >    web_privado_perfil_modificar.ButtonGuardar_Click(Object sender,
> >   > EventArgs e) in c:\Documents and Settings\César Díaz García\Mis
> >   > documentos\Visual Studio 2005\WebSites\proyecto\web\privado
> >   > \perfil_modificar.aspx.cs:50
> >   >    System.Web.UI.WebControls.Button.OnClick(EventArgs e) +96
> >   >    System.Web.UI.WebControls.Button.RaisePostBackEvent(String
> >   > eventArgument) +116
>
> System.Web.UI.WebControls.Button.System.Web.UI.IPostBackEventHandler.RaisePo
> stBackEvent(String
> >   > eventArgument) +31
> >   >    System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler
> >   > sourceControl, String eventArgument) +32
> >   >    System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData)
> >   > +72
> >   >    System.Web.UI.Page.ProcessRequestMain(Boolean
> >   > includeStagesBeforeAsyncPoint, Boolean
>
> ...
>
> leer más »
>
>  TestConn.zip
> 13 KDescargar


--~--~---------~--~----~------------~-------~--~----~
Para escribir al Grupo, hágalo a esta dirección: 
[email protected]
Para más, visite: http://groups-beta.google.com/group/NHibernate-Hispano
-~----------~----~----~----~------~----~------~--~---

Responder a