Hibernate version: 1.2.0
Hi,
I'm trying to get a bindinglist as result of a one-to-many relation.
When a set my property type to bindinglist(Of T), i get this error :
Quote:
NHibernate.MappingException was unhandled
Message="Invalid mapping information specified for type MonNameSpace.clsEntreprise, check your mapping file for property type mismatches"
Source="NHibernate"
StackTrace:
at NHibernate.Persister.Entity.AbstractEntityPersister.SetPropertyValues(Object obj, Object[] values)
at NHibernate.Impl.SessionImpl.InitializeEntity(Object obj)
at NHibernate.Loader.Loader.InitializeEntitiesAndCollections(IList hydratedObjects, Object resultSetId, ISessionImplementor session)
at NHibernate.Loader.Loader.DoQuery(ISessionImplementor session, QueryParameters queryParameters, Boolean returnProxies)
at NHibernate.Loader.Loader.DoQueryAndInitializeNonLazyCollections(ISessionImplementor session, QueryParameters queryParameters, Boolean returnProxies)
at NHibernate.Loader.Loader.LoadEntity(ISessionImplementor session, Object id, IType identifierType, Object optionalObject, Type optionalEntityName, Object optionalIdentifier, IEntityPersister persister)
at NHibernate.Loader.Entity.AbstractEntityLoader.Load(ISessionImplementor session, Object id, Object optionalObject, Object optionalId)
at NHibernate.Loader.Entity.AbstractEntityLoader.Load(Object id, Object optionalObject, ISessionImplementor session)
at NHibernate.Persister.Entity.AbstractEntityPersister.Load(Object id, Object optionalObject, LockMode lockMode, ISessionImplementor session)
at NHibernate.Impl.SessionImpl.DoLoad(Type theClass, Object id, Object optionalObject, LockMode lockMode, Boolean checkDeleted)
at NHibernate.Impl.SessionImpl.DoLoadByClass(Type clazz, Object id, Boolean checkDeleted, Boolean allowProxyCreation)
at NHibernate.Impl.SessionImpl.Load(Type clazz, Object id)
at MonNameSpace.facEntreprise.SelectOne(Int32 EntrepriseID) in C:\Documents and Settings\cdl\Desktop\test2\test2\test2\factory\facEntreprise.vb:line 19
at MonNameSpace.Form1.Form1_Load(Object sender, EventArgs e) in C:\Documents and Settings\cdl\Desktop\test2\test2\test2\Form1.vb:line 11
at System.EventHandler.Invoke(Object sender, EventArgs e)
at System.Windows.Forms.Form.OnLoad(EventArgs e)
at System.Windows.Forms.Form.OnCreateControl()
at System.Windows.Forms.Control.CreateControl(Boolean fIgnoreVisible)
at System.Windows.Forms.Control.CreateControl()
at System.Windows.Forms.Control.WmShowWindow(Message& m)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ScrollableControl.WndProc(Message& m)
at System.Windows.Forms.ContainerControl.WndProc(Message& m)
at System.Windows.Forms.Form.WmShowWindow(Message& m)
at System.Windows.Forms.Form.WndProc(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
at System.Windows.Forms.SafeNativeMethods.ShowWindow(HandleRef hWnd, Int32 nCmdShow)
at System.Windows.Forms.Control.SetVisibleCore(Boolean value)
at System.Windows.Forms.Form.SetVisibleCore(Boolean value)
at System.Windows.Forms.Control.set_Visible(Boolean value)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.Run(ApplicationContext context)
at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.OnRun()
at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.DoApplicationModel()
at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.Run(String[] commandLine)
at MonNameSpace.My.MyApplication.Main(String[] Args) in 17d14f5c-a337-4978-8281-53493378c1071.vb:line 81
at System.AppDomain.nExecuteAssembly(Assembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
With this inner error :
Quote:
{"Unable to cast object of type 'NHibernate.Collection.Generic.PersistentGenericBag`1[MonNameSpace.clsAdresse]' to type 'System.ComponentModel.BindingList`1[MonNameSpace.clsAdresse]'."}
So I decided to create a custom Collection which Inherits BindingList(Of T), and i found some example, to Implements IUserCollectionType.
Here the code :
Mapping :
Code:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
<class name="MonNameSpace.clsEntreprise, MonAssembly" table="tblEntreprises">
<id name="EntrepriseID" column="EntrepriseID" type="Int32">
<generator class="identity" />
</id>
<property name="Nom" column="Nom" type="String" length="50" />
<property name="CompteBancaire" column="CompteBancaire" type="String" length="30" />
<property name="Iban" column="Iban" type="String" length="30" />
<property name="Swift" column="Swift" type="String" length="30" />
<property name="NoTva" column="NoTva" type="String" length="20" />
<property name="NoSun" column="NoSun" type="String" length="20" />
<property name="Tel" column="Tel" type="String" length="20" />
<property name="Fax" column="Fax" type="String" length="20" />
<property name="Email" column="Email" type="String" length="50" />
<property name="Site" column="Site" type="String" length="50" />
<property name="Langue" column="Langue" type="String" length="10" />
<property name="Info" column="Info" type="String" length="500" />
<property name="Supprime" column="Supprime" type="Boolean" />
<property name="ChangeDate" column="ChangeDate" type="DateTime" />
<property name="ChangeUser" column="ChangeUser" type="String" length="20" />
<property name="Flag" column="Flag" type="Int32" length="1" />
<bag name="Adresses" cascade="save-update" collection-type="MonNameSpace.MaListe`1[[MonNameSpace.clsAdresse, MonAssembly]],MonAssembly">
<key column="EntrepriseID"/>
<one-to-many class="MonNameSpace.clsAdresse, MonAssembly"/>
</bag>
</class>
</hibernate-mapping>
Code:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
<class name="MonNameSpace.clsAdresse, MonAssembly" table="tblAdresses" dynamic-update="true">
<id name="AdresseID" column="AdresseID" type="Int32">
<generator class="identity" />
</id>
<property name="EntrepriseID" column="EntrepriseID" type="Int32" length="4" />
<property name="Rue" column="Rue" type="String" length="50" />
</class>
</hibernate-mapping>
Data Access :Code:
Public Class clsEntreprise
Protected m_EntrepriseID As Integer
Protected m_Nom As String
Protected m_CompteBancaire As String
Protected m_Iban As String
Protected m_Swift As String
Protected m_NoTva As String
Protected m_NoSun As String
Protected m_Tel As String
Protected m_Fax As String
Protected m_Email As String
Protected m_Site As String
Protected m_Langue As String
Protected m_Info As String
Protected m_Supprime As Boolean
Protected m_ChangeDate As Date
Protected m_ChangeUser As String
Protected m_Flag As Integer
Private m_IListAdresses As IMaListe(Of clsAdresse) = New MaListe(Of clsAdresse)()
Public Overridable Property EntrepriseID() As Integer
Get
Return m_EntrepriseID
End Get
Set(ByVal value As Integer)
m_EntrepriseID = value
End Set
End Property
Public Overridable Property Nom() As String
Get
Return m_Nom
End Get
Set(ByVal value As String)
m_Nom = value
End Set
End Property
...
...
Public Overridable Property Adresses() As IMaListe(Of clsAdresse)
Get
Return m_IListAdresses
End Get
Set(ByVal Value As IMaListe(Of clsAdresse))
m_IListAdresses = Value
End Set
End Property
End Class
Code:
Public Class clsAdresse
Protected m_AdresseID As Integer
Protected m_EntrepriseID As Integer
Protected m_Rue As String
Public Overridable Property AdresseID() As Integer
Get
Return m_AdresseID
End Get
Set(ByVal value As Integer)
m_AdresseID = value
End Set
End Property
Public Overridable Property EntrepriseID() As Integer
Get
Return m_EntrepriseID
End Get
Set(ByVal value As Integer)
m_EntrepriseID = value
End Set
End Property
Public Overridable Property Rue() As String
Get
Return m_Rue
End Get
Set(ByVal value As String)
m_Rue = value
End Set
End Property
End Class
UserCollection :Code:
Imports NHibernate.Engine
Imports NHibernate.UserTypes
Imports NHibernate.Collection
Imports NHibernate.Collection.Generic
Imports NHibernate.Persister.Collection
Imports System.ComponentModel
Imports System.Collections
Imports System.Collections.Specialized
Public Class MaListe(Of T)
Inherits BindingList(Of T)
Implements IMaListe(Of T), IUserCollectionType
#Region "IUserCollectionType Implementation"
Public Function Instantiate(ByVal session As ISessionImplementor, ByVal persister As ICollectionPersister) As IPersistentCollection Implements IUserCollectionType.Instantiate
Return New PersistentGenericMaListeBag(Of T)(session)
End Function
Public Function Wrap(ByVal session As ISessionImplementor, ByVal collection As Object) As IPersistentCollection Implements IUserCollectionType.Wrap
Return New PersistentGenericMaListeBag(Of T)(session, CType(collection, MaListe(Of T)))
End Function
Public Function GetElements(ByVal collection As Object) As IEnumerable Implements IUserCollectionType.GetElements
Return CType(collection, IEnumerable)
End Function
Public Function Contains(ByVal collection As Object, ByVal entity As Object) As Boolean Implements IUserCollectionType.Contains
Return (CType(collection, IMaListe(Of T))).Contains(CType(entity, T))
End Function
Public Function IndexOf(ByVal collection As Object, ByVal entity As Object) As Object Implements IUserCollectionType.IndexOf
Return (CType(collection, IList(Of T))).IndexOf(CType(entity, T))
End Function
Public Function ReplaceElements(ByVal original As Object, ByVal target As Object, ByVal persister As ICollectionPersister, ByVal owner As Object, ByVal copyCache As System.Collections.IDictionary, ByVal session As ISessionImplementor) As Object Implements IUserCollectionType.ReplaceElements
Dim Result As IMaListe(Of T) = CType(target, IMaListe(Of T))
Result.Clear()
For Each item As Object In (CType(original, IEnumerable))
Result.Add(CType(item, T))
Next
Return Result
End Function
Public Function Instantiate() As Object Implements IUserCollectionType.Instantiate
Return New MaListe(Of T)()
End Function
#End Region
IUserCollection :Code:
Imports System.Collections.Generic
Imports System.ComponentModel
Imports System.Collections
Imports System.Collections.Specialized
Public Interface IMaListe(Of T)
Inherits IBindingList
End Interface
Persistent Wrapper :Code:
Imports NHibernate.Engine
Imports NHibernate.Collection.Generic
Public Class PersistentGenericMaListeBag(Of T)
Inherits PersistentGenericBag(Of T)
Implements IMaListe(Of T)
Public Sub New(ByVal session As ISessionImplementor, ByVal list As MaListe(Of T))
MyBase.New(session, list)
End Sub
Public Sub New(ByVal session As ISessionImplementor)
MyBase.New(session)
End Sub
#Region "IBindingList Implementation"
Public Sub AddIndex(ByVal [property] As System.ComponentModel.PropertyDescriptor) Implements System.ComponentModel.IBindingList.AddIndex
End Sub
Public Function AddNew() As Object Implements System.ComponentModel.IBindingList.AddNew
Return False
End Function
Public ReadOnly Property AllowEdit() As Boolean Implements System.ComponentModel.IBindingList.AllowEdit
Get
Return False
End Get
End Property
Public ReadOnly Property AllowNew() As Boolean Implements System.ComponentModel.IBindingList.AllowNew
Get
Return False
End Get
End Property
Public ReadOnly Property AllowRemove() As Boolean Implements System.ComponentModel.IBindingList.AllowRemove
Get
Return False
End Get
End Property
Public Sub ApplySort(ByVal [property] As System.ComponentModel.PropertyDescriptor, ByVal direction As System.ComponentModel.ListSortDirection) Implements System.ComponentModel.IBindingList.ApplySort
End Sub
Public Function Find(ByVal [property] As System.ComponentModel.PropertyDescriptor, ByVal key As Object) As Integer Implements System.ComponentModel.IBindingList.Find
End Function
Public ReadOnly Property IsSorted() As Boolean Implements System.ComponentModel.IBindingList.IsSorted
Get
Return False
End Get
End Property
Public Event ListChanged(ByVal sender As Object, ByVal e As System.ComponentModel.ListChangedEventArgs) Implements System.ComponentModel.IBindingList.ListChanged
Public Sub RemoveIndex(ByVal [property] As System.ComponentModel.PropertyDescriptor) Implements System.ComponentModel.IBindingList.RemoveIndex
End Sub
Public Sub RemoveSort() Implements System.ComponentModel.IBindingList.RemoveSort
End Sub
Public ReadOnly Property SortDirection() As System.ComponentModel.ListSortDirection Implements System.ComponentModel.IBindingList.SortDirection
Get
Return System.ComponentModel.ListSortDirection.Descending
End Get
End Property
Private m_SortProperty As System.ComponentModel.PropertyDescriptor
Public ReadOnly Property SortProperty() As System.ComponentModel.PropertyDescriptor Implements System.ComponentModel.IBindingList.SortProperty
Get
Return m_SortProperty
End Get
End Property
Public ReadOnly Property SupportsChangeNotification() As Boolean Implements System.ComponentModel.IBindingList.SupportsChangeNotification
Get
Return False
End Get
End Property
Public ReadOnly Property SupportsSearching() As Boolean Implements System.ComponentModel.IBindingList.SupportsSearching
Get
Return False
End Get
End Property
Public ReadOnly Property SupportsSorting() As Boolean Implements System.ComponentModel.IBindingList.SupportsSorting
Get
Return False
End Get
End Property
#End Region
Factory :Code:
Imports NHibernate
Imports NHibernate.Cfg
Public Class facEntreprise
Public Shared Function SelectOne(ByVal EntrepriseID As Integer) As clsEntreprise
Dim cfg As New Configuration()
cfg.AddAssembly("MonAssembly")
Dim factory As ISessionFactory = cfg.BuildSessionFactory()
Dim session As ISession = factory.OpenSession()
Return session.Load(GetType(clsEntreprise), EntrepriseID)
session.Close()
End Function
End Class
-----------------------------------------------------------------------------
So, i can use this :
Code:
facEntreprise.SelectOne(117).Adresses
Which return a IMaList(Of MonNameSpace.clsAdresse)
Now, I want add some custom function to my collection MaList(Of T).
When i do that, I don't see them the IMaList return.
So i add them to the Interface IMaList, and then, i must Implement them in the persistent wrapper PersistentGenericMaListeBag(Of T).
Finally, the used code is the one in PersistentGenericMaListeBag(Of T), not the one in MaList(Of T)...
So i must write my code 2 times ?
There isn't a easier/simpler way to use Bindinglist and/or custom collection ?