-->
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.  [ 9 posts ] 
Author Message
 Post subject: How i have to map an association with Proxy interfaces?
PostPosted: Sun Sep 10, 2006 6:19 pm 
Newbie

Joined: Thu Aug 31, 2006 7:54 am
Posts: 6
I have some problems with the mapping of an association with classes that have proxy interface. I don't understand if i have to declare a collection of the interface type (es. ISet<IPerson>) or a collection of Concrete class (es Set<Person>) because i have problem in all the 2 ways... Could someone explain me how is the correct mapping of collection when the classes have a proxy interface specified?

Thanks
Daniele

1.2.0.0001 alpha 1



public abstract class GenericBO<IdT> : IGenericBO<IdT>
{
public IdT Id
{
get { return id; }
set { id = value; }
}

private IdT id = default(IdT);
}

public interface IGenericBO<IdT>
{
IdT Id { get; set; }
}


public class Appartamento : GenericBO<Int32>, IAppartamento
{
private String codice;
private String nome;
private ICollection<IFoto> foto;

public string Codice
{
get { return codice; }
set { codice = value; }
}

public string Nome
{
get { return nome; }
set { nome = value; }
}

public ICollection<IFoto> Foto
{
get { return foto; }
set { foto = value; }
}
}

public interface IAppartamento : IGenericBO<Int32>
{
string Codice { get; set; }

string Nome { get; set; }

ICollection<IFoto> Foto { get; set; }

}


public interface IFoto: IGenericBO<Int32>
{
string Path { get; set; }

IAppartamento Appartamento { get; set; }
}

public class Foto : GenericBO<Int32>, IFoto
{
private String path;
private IAppartamento appartamento;

public string Path
{
get { return path; }
set { path = value; }
}

public IAppartamento Appartamento
{
get { return appartamento; }
set { appartamento = value; }
}
}

<class name="Appartamento" table="Appartamenti" proxy="IAppartamento">
<id name="Id" column="Id" type="Int32">
<generator class="native"/>
</id>
<property name="Codice" column="Codice" type="String"></property>
<property name="Nome" column="Nome" type="String"></property>
<property name="Descrizione" column="Descrizione" type="String"></property>
<set name="Foto" lazy="true" inverse="true">
<key column="IdAppartamento" />
<one-to-many class="Foto"/>
</set>
</class>
<class name="Foto" table="Foto" proxy="IFoto">
<id name="Id" column="Id" type="Int32">
<generator class="native"/>
</id>
<property name="Path" column="Path" type="String"></property>
<many-to-one name="Appartamento" foreign-key="Id">
<column name="IdAppartamento"/>
</many-to-one>
</class>








MappingException: An association from the table Foto refers to an unmapped class: IAppartamento]
Daffini.DataAccess.NH.SessionManager.InitSessionFactory() in D:\Lavori\Progetti\Daffini.DataAccess\NHibernate\SessionManager.cs:65
Daffini.DataAccess.NH.SessionManager..ctor() in D:\Lavori\Progetti\Daffini.DataAccess\NHibernate\SessionManager.cs:27
Daffini.DataAccess.NH.Nested..cctor() in D:\Lavori\Progetti\Daffini.DataAccess\NHibernate\SessionManager.cs:39

[TypeInitializationException: The type initializer for 'Nested' threw an exception.]
Daffini.DataAccess.NH.SessionManager.get_Instance() in D:\Lavori\Progetti\Daffini.DataAccess\NHibernate\SessionManager.cs:19
Daffini.DataAccess.Web.SessionHttpModule.CommitAndCloseSession(Object sender, EventArgs e) in D:\Lavori\Progetti\Daffini.DataAccess\Web\SessionHttpModule.cs:59
System.Web.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +167
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +117


Sql server express 2005


Top
 Profile  
 
 Post subject: Re: How i have to map an association with Proxy interfaces?
PostPosted: Mon Sep 11, 2006 3:01 am 
Expert
Expert

Joined: Thu Jan 19, 2006 4:29 pm
Posts: 348
daffini wrote:
I have some problems with the mapping of an association with classes that have proxy interface. I don't understand if i have to declare a collection of the interface type (es. ISet<IPerson>) or a collection of Concrete class (es Set<Person>) because i have problem in all the 2 ways... Could someone explain me how is the correct mapping of collection when the classes have a proxy interface specified?


The collection itself must always by interface ( ISet<T>). And it seems that ISet<IFoto> mapping should work Ok.

But: You have problem in

Code:
<many-to-one name="Appartamento" foreign-key="Id">
  <column name="IdAppartamento"/>
</many-to-one>


As You do not define the association target class, NHibernate uses reflection to guess the type, it founds it to be IAppartamento which is unmapped. Add class attribute to fix it..

Gert

_________________
If a reply helps You, rate it!


Top
 Profile  
 
 Post subject: Re: How i have to map an association with Proxy interfaces?
PostPosted: Mon Sep 11, 2006 4:17 am 
Newbie

Joined: Thu Aug 31, 2006 7:54 am
Posts: 6
gert wrote:
daffini wrote:
]

As You do not define the association target class, NHibernate uses reflection to guess the type, it founds it to be IAppartamento which is unmapped. Add class attribute to fix it..

Gert


Thank you very much Gert.. you're kind..
you're suggest solve my problem.


Top
 Profile  
 
 Post subject: I have another problem on the same project
PostPosted: Wed Sep 20, 2006 8:42 am 
Newbie

Joined: Thu Aug 31, 2006 7:54 am
Posts: 6
If i write the code below always going well...

ICriteria criteria = session.CreateCriteria(typeof(Appartamento));
IList<IAppartamento> appartamenti = criteria.List<IAppartamento>();
appartamenti.GetEnumerator().MoveNext();
IAppartamento appartamento = appartamenti.GetEnumerator().Current;
Response.write(appartamento.Id);

But if i modify the code like this:

**new line**
ICriteria criteria = session.CreateCriteria(typeof(Foto));
IList<IFoto> appartamenti = criteria.List<IFoto>();
** **
ICriteria criteria = session.CreateCriteria(typeof(Appartamento));
IList<IAppartamento> appartamenti = criteria.List<IAppartamento>();
appartamenti.GetEnumerator().MoveNext();
IAppartamento appartamento = appartamenti.GetEnumerator().Current;
Response.write(appartamento.Id);

I received the following error:

System.ArgumentException: Cannot resolve method Int32 get_Id() because the declaring type of the method handle Daffini.DataAccess.Domain.IGenericBO`1[IdT] is generic. Explicitly provide the declaring type to GetMethodFromHandle.

[ArgumentException: Cannot resolve method Int32 get_Id() because the declaring type of the method handle Daffini.DataAccess.Domain.IGenericBO`1[IdT] is generic. Explicitly provide the declaring type to GetMethodFromHandle. ]
System.Reflection.MethodBase.GetMethodFromHandle(RuntimeMethodHandle handle) +2335793
ProxyInterfaceSystemObject_IAppartamento_INHibernateProxy_ISerializable.get_Id() +58

[TargetInvocationException: Property accessor 'Id' on object 'ProxyInterfaceSystemObject_IAppartamento_INHibernateProxy_ISerializable' threw the following exception:'Cannot resolve method Int32 get_Id() because the declaring type of the method handle Daffini.DataAccess.Domain.IGenericBO`1[IdT] is generic. Explicitly provide the declaring type to GetMethodFromHandle. ']
System.ComponentModel.ReflectPropertyDescriptor.GetValue(Object component) +499
System.Web.UI.DataBinder.GetPropertyValue(Object container, String propName) +186
System.Web.UI.DataBinder.Eval(Object container, String[] expressionParts) +120
System.Web.UI.DataBinder.Eval(Object container, String expression) +173
ASP.listapartments_aspx.__DataBind__control4(Object sender, EventArgs e) in d:\Lavori\Progetti\Natalia\Appartamenti-Kiev\ListApartments.aspx:23
System.Web.UI.Control.OnDataBinding(EventArgs e) +88
System.Web.UI.Control.DataBind(Boolean raiseOnDataBinding) +167
System.Web.UI.Control.DataBind() +31
System.Web.UI.Control.DataBindChildren() +236
System.Web.UI.Control.DataBind(Boolean raiseOnDataBinding) +178
System.Web.UI.Control.DataBind() +31
System.Web.UI.WebControls.Repeater.CreateItem(Int32 itemIndex, ListItemType itemType, Boolean dataBind, Object dataItem) +160
System.Web.UI.WebControls.Repeater.CreateControlHierarchy(Boolean useDataSource) +539
System.Web.UI.WebControls.Repeater.OnDataBinding(EventArgs e) +72
System.Web.UI.WebControls.Repeater.DataBind() +86
ListApartments.set_Appartamenti(IList`1 value) in d:\Lavori\Progetti\Natalia\Appartamenti-Kiev\ListApartments.aspx.cs:36
Daffini.AppartamentiKiev.Presentation.Presenter.ListApartmentsPresenter.Initialize() in D:\Lavori\Progetti\Natalia\Daffini.AppartamentiKiev.Presentation\Presenter\ListApartmentsPresenter.cs:25
ListApartments.Page_Load(Object sender, EventArgs e) in d:\Lavori\Progetti\Natalia\Appartamenti-Kiev\ListApartments.aspx.cs:16
System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp, Object o, Object t, EventArgs e) +31
System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object sender, EventArgs e) +68
System.Web.UI.Control.OnLoad(EventArgs e) +88
System.Web.UI.Control.LoadRecursive() +74
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +3036



The problem is only on the "ID" property. If I read all the other property except ID all going well..


Top
 Profile  
 
 Post subject: Re: I have another problem on the same project
PostPosted: Wed Sep 20, 2006 9:07 am 
Expert
Expert

Joined: Thu Jan 19, 2006 4:29 pm
Posts: 348
daffini wrote:
**new line**
ICriteria criteria = session.CreateCriteria(typeof(Foto));
IList<IFoto> appartamenti = criteria.List<IFoto>();
** **
ICriteria criteria = session.CreateCriteria(typeof(Appartamento));
IList<IAppartamento> appartamenti = criteria.List<IAppartamento>();
appartamenti.GetEnumerator().MoveNext();
IAppartamento appartamento = appartamenti.GetEnumerator().Current;
Response.write(appartamento.Id);

I received the following error:

System.ArgumentException: Cannot resolve method Int32 get_Id() because the declaring type of the method handle Daffini.DataAccess.Domain.IGenericBO`1[IdT] is generic. Explicitly provide the declaring type to GetMethodFromHandle.


Sounds like the Castle.DynamicProxy is not handling generic interfaces correctly.. And, with quick search,
http://forum.castleproject.org/viewtopic.php?t=866&highlight=generic

So, You propably must give up lazy loading (== remove "proxy" attributes from mapping), or remove the IGenericBO<IdT> interface.

EDIT: After a second thought, if You might be able to get this fixed by DynamicProxy team - after all, the IAppartemento interface is not generic any more...

Gert

_________________
If a reply helps You, rate it!


Top
 Profile  
 
 Post subject: Re: I have another problem on the same project
PostPosted: Wed Sep 20, 2006 10:51 am 
Newbie

Joined: Thu Aug 31, 2006 7:54 am
Posts: 6
Ok, thanks again.. i don't happy of this.. but it seems to work... :-)
If i understand, is a limit of Castle.DinamicProxy?

And another question.. i want to write a generici Equals method, and i write in the GenericBO classes a method like this..

public override bool Equals(object obj)
{
if (obj == null || GetType() != obj.GetType())
{
return false;
}

return ((IGenericBO<IdT>) obj).Id.Equals(Id);
}

With lazy loading this test is always false because if the object come from a collection it's type is ProxyInterfaceSystemObject_IAppartamento_INHibernateProxy_ISerializable

There is a way to code a general Equals method for all my business object?


Top
 Profile  
 
 Post subject: Re: I have another problem on the same project
PostPosted: Wed Sep 20, 2006 11:13 am 
Expert
Expert

Joined: Thu Jan 19, 2006 4:29 pm
Posts: 348
daffini wrote:
Ok, thanks again.. i don't happy of this.. but it seems to work... :-)
If i understand, is a limit of Castle.DinamicProxy?


I do not know DynamicProxy well enought to tell. It might be problem in how NHibernate uses DynamicProxy...

daffini wrote:
And another question.. i want to write a generici Equals method, and i write in the GenericBO classes a method like this..

public override bool Equals(object obj)
{
if (obj == null || GetType() != obj.GetType())
{
return false;
}

return ((IGenericBO<IdT>) obj).Id.Equals(Id);
}

With lazy loading this test is always false because if the object come from a collection it's type is ProxyInterfaceSystemObject_IAppartamento_INHibernateProxy_ISerializable

There is a way to code a general Equals method for all my business object?


I do not have good ideas... Maybe someone else?

Gert

_________________
If a reply helps You, rate it!


Top
 Profile  
 
 Post subject: Re: I have another problem on the same project
PostPosted: Wed Sep 20, 2006 11:49 am 
Newbie

Joined: Thu Aug 31, 2006 7:54 am
Posts: 6
gert wrote:

I do not have good ideas... Maybe someone else?

Gert



The only solution that i found is this.. http://cs.nerdbank.net/blogs/jmpinline/ ... 4/126.aspx

But i have to implement a similar Equals method in all my business object...


Top
 Profile  
 
 Post subject: Re: I have another problem on the same project
PostPosted: Thu Sep 21, 2006 7:16 am 
Newbie

Joined: Thu Aug 31, 2006 7:54 am
Posts: 6
daffini wrote:
gert wrote:

I do not have good ideas... Maybe someone else?

Gert



The only solution that i found is this.. http://cs.nerdbank.net/blogs/jmpinline/ ... 4/126.aspx

But i have to implement a similar Equals method in all my business object...



I finally the solve the problem with a code like this :

public override bool Equals(object obj)
{
if (obj == this) return true;

obj = getImplementation(obj);
if (obj.GetType() != GetType() ) return false;
return Id.Equals(((GenericBO<IdT>) obj).Id);

}

protected object getImplementation(object obj)
{
if (obj is INHibernateProxy)
{
return NHibernateProxyHelper.GetLazyInitializer((INHibernateProxy) obj).GetImplementation();
}
else
{
return obj;
}
}

I've before tryed to use
public override bool Equals(object obj)
{
if (obj == this) return true;

NHibernate.NHibernateUtil.Initialize(obj);
if (obj.GetType() != GetType() ) return false;
return Id.Equals(((GenericBO<IdT>) obj).Id);

}

but it doesn't work...


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 9 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.