-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 6 posts ] 
Author Message
 Post subject: Not using DTO
PostPosted: Mon Aug 06, 2007 11:10 am 
Beginner
Beginner

Joined: Mon Mar 06, 2006 2:19 pm
Posts: 42
Location: Belo Horizonte, Brazil
Hibernate version: 1.2.0.GA

Hi. I am one of those that is using NHibernate with Win Forms and Remoting. I'm not using DTO and following the Hibernate in Action example, I send my business objects to the client program. I've noticed that because of this, I had to add to the client side 3 assemblies:

NHibernate.dll, Log4net.dll and Castle.DynamicProxy.dll.

Is this correct? I think I don't have too much option because NHibernate modify the original objects. I can't even test if a collection is null when I don't bring it, because it is a proxy.

Is there a way to "clean" the objects before sending them to the client side?

Thank you


Top
 Profile  
 
 Post subject:
PostPosted: Tue Aug 07, 2007 1:24 am 
Regular
Regular

Joined: Tue Feb 21, 2006 9:50 am
Posts: 107
Castle.DynamicProxy.dll implements the proxy classes for lazy loaded collections.

If you use NHibernate with remoting you have to ensure that your business objects, and specially the collections inside, are completely initialized from the database before sending it to the client. You can ensure this either via the "lazy=false" attribute in your collection mappings or using NHibernateUtil.Initialize(object) method. I haven't tried it, but i think "lazy=false" is the only way to prevent NHibernate to instantiate proxies for collections. So this may be the only way to prevent including Castle.DynamicProxy to your client.

I don't know why you have to add a reference to NHibernate.dll to your client. Normally, if you don't use any NHibernate functionality in your client nor in your business objects there should be no need to do this. For the collections in your business objects you may have to add Iesi.Collections if you use the <bag> element in your mappings.

I'm just writing a WinForms application which use NHibernate to handle data structures in a document oriented way (that is read the whole object tree into memory, manipulate the data, and then write the whole object tree back). Our business object has around 50 classes with nested collections up to 5 levels deep and one business object may consist of several hundred databse records. Our client can access the database dircectly or via remoting. We also don't use DTOs and haven't found any problems to use the objects instantiated by NHibernate directly. But, because of the document oriented style of our application, we defined all collection mappings with "lazy=false".

Regards
Klaus


Top
 Profile  
 
 Post subject:
PostPosted: Tue Aug 07, 2007 2:02 pm 
Beginner
Beginner

Joined: Mon Mar 06, 2006 2:19 pm
Posts: 42
Location: Belo Horizonte, Brazil
Hi Klaus,

Using lazy=false is not a good solution to me. I just want to load what I will use. If there is a collection not initialized I would like to be null or Count=0.

I'm still thinking write a function that runs through the object graph and initialize all properties and lists. There must be an easy way to return the objects like they were designed.

I've done a test. I really need Nhibernate.dll, Log4net.dll and Castle.DynamicProxy.dll. My business objects don't have reference to them but I still have to add them in my client project.

The worst of all is that I am receiving this error when the server sends data to client. Without changing any line in the code, just rebuilding the projects 2 or 3 times, everything works fine. I didn't have this error when I was using specific DTO's.


Quote:
Exception has been thrown by the target of an invocation.

Server stack trace:
em System.RuntimeMethodHandle._SerializationInvoke(Object target, SignatureStruct& declaringTypeSig, SerializationInfo info, StreamingContext context)
em System.RuntimeMethodHandle.SerializationInvoke(Object target, SignatureStruct declaringTypeSig, SerializationInfo info, StreamingContext context)
em System.Reflection.RuntimeConstructorInfo.SerializationInvoke(Object target, SerializationInfo info, StreamingContext context)
em System.Runtime.Serialization.ObjectManager.CompleteISerializableObject(Object obj, SerializationInfo info, StreamingContext context)
em System.Runtime.Serialization.ObjectManager.FixupSpecialObject(ObjectHolder holder)
em System.Runtime.Serialization.ObjectManager.DoFixups()
em System.Runtime.Serialization.Formatters.Binary.ObjectReader.Deserialize(HeaderHandler handler, __BinaryParser serParser, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)
em System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream, HeaderHandler handler, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)
em System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.UnsafeDeserializeMethodResponse(Stream serializationStream, HeaderHandler handler, IMethodCallMessage methodCallMessage)
em System.Runtime.Remoting.Channels.CoreChannel.DeserializeBinaryResponseMessage(Stream inputStream, IMethodCallMessage reqMsg, Boolean bStrictBinding)
em System.Runtime.Remoting.Channels.BinaryClientFormatterSink.DeserializeMessage(IMethodCallMessage mcm, ITransportHeaders headers, Stream stream)
em System.Runtime.Remoting.Channels.BinaryClientFormatterSink.SyncProcessMessage(IMessage msg)

Exception rethrown at [0]:
em System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
em System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
em Noventa.Regente.Modulo.Contratos.Controle.ICSocioContrato.ListarSocios(Int64 contrato_id)
em Noventa.Regente.Modulo.Contratos.Tela.FSocioContrato.ListarSocios() na D:\Fontes\regente.net\cliente\Contrato.Tela\FSocioContrato.cs:linha 165
em Noventa.Regente.Modulo.Contratos.Tela.FSocioContrato.FSocioContrato_Load(Object sender, EventArgs e) na D:\Fontes\regente.net\cliente\Contrato.Tela\FSocioContrato.cs:linha 93


The object of type 'System.Decimal' can't be converted in type 'System.Int64'.

em System.RuntimeType.CheckValue(Object value, Binder binder, CultureInfo culture, BindingFlags invokeAttr)
em System.Reflection.RtFieldInfo.InternalSetValue(Object obj, Object value, BindingFlags invokeAttr, Binder binder, CultureInfo culture, Boolean doVisibilityCheck, Boolean doCheckConsistency)
em System.Runtime.Serialization.FormatterServices.SerializationSetValue(MemberInfo fi, Object target, Object value)
em System.Runtime.Serialization.FormatterServices.PopulateObjectMembers(Object obj, MemberInfo[] members, Object[] data)
em Castle.DynamicProxy.Serialization.ProxyObjectReference.RecreateClassProxy(SerializationInfo info, StreamingContext context)
em Castle.DynamicProxy.Serialization.ProxyObjectReference.RecreateProxy(SerializationInfo info, StreamingContext context)
em Castle.DynamicProxy.Serialization.ProxyObjectReference..ctor(SerializationInfo info, StreamingContext context)



I found this post at hibernate forum with the context

http://forum.hibernate.org/viewtopic.php?t=964452&highlight=dto


Thank you


Top
 Profile  
 
 Post subject:
PostPosted: Wed Aug 08, 2007 2:02 am 
Regular
Regular

Joined: Tue Feb 21, 2006 9:50 am
Posts: 107
if you take a look at the internals of the objects, which NHibernate cretaes, you will see why you have to add the references: Castle.dynamicProxy you have to add to your client because of the lazy collections. NHibernate you have to reference because of the <bag> element in the mapping file for the n-side of a relation. This elements are instantiated as NHibernate.Collections.Bag. Log4Net you have to add because nHibernate use it for debug output. If you want to omit these references, i'm afraid you have to use DTO's.

When i implement my mapping, i make some thoughts about the database and object relations (mostly i have to write an application against an existing database, only in rare cases i can start from scratch). If i don't need a relation which exists on the database in my application context, i don't write a mapping for it. On the other hand, if i need the relation in rare cases, i will write two different mappings (which implies that i have two different business objects). If the data is used readonly (like overview lists for example) i will use views on the database which will do all the joins for me and create a mapping for the view. You may use views also to read the data you want to edit. But you have to transform them to a business object before updating.

As the lazy collections throws exceptions if they are acessed and not initialized, a simple way will be to embed the access to a collection in a trycatch block. If you really want a behavior like normal collections, i'm afraid you have to write the code you think about.

To your exception i'm afraid i can't help you. I never got such an error, neither in NHibernate context nor in .NET Remoting context.

Regards
Klaus


Top
 Profile  
 
 Post subject:
PostPosted: Wed Aug 08, 2007 8:51 am 
Beginner
Beginner

Joined: Mon Mar 06, 2006 2:19 pm
Posts: 42
Location: Belo Horizonte, Brazil
Hi Klaus,

Thank you very much, you helped me a lot.

Just one last question. Do you add these 3 assemblies (nhibernate, castle, log) as references or existing items? I'm asking because I generally add as reference when my code explicity have to use an element inside the assembly. In this case we're adding these assemblies just to have them in our final bin, so I thought that using "add existing item" in VS would be the right choice, but I'm not sure.

Thank you


Top
 Profile  
 
 Post subject:
PostPosted: Thu Aug 09, 2007 12:54 am 
Regular
Regular

Joined: Tue Feb 21, 2006 9:50 am
Posts: 107
i added the libraries as references, but this is because i use NHibernate on the client and on the server (my application is a mix between Client/Server and N-Tier).

Regards
Klaus


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 6 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.