how to map a collection of items that have composite ids

115 views
Skip to first unread message

epitka

unread,
Mar 16, 2009, 12:54:59 PM3/16/09
to nhusers
Hi, I am trying to map a collection (bag) or items that have composite
id. The mapping I have throws an error saying that

NHibernate.FKUnmatchingColumnsException: Foreign key
(FK6A7D859A4C8DCC7F:ClientAcctType [ClientId, EffectiveDate])) must
have same number of columns as the referenced primary key (Client
[ClientId])

I have a Client and ClientAcctType tables where ClientAcctType is
basically a history table. So I want to map this history for specific
Client. I created a ClientAccountTypeCompositeID class and mapped the
history item like this

ClientAcctountTypeHistoryItem:
<composite-id class="ClientAccountTypeCompositeID"
name="Id" access="lowercase-underscore">
<key-property name="ClientID" access="property"
column="ClientId"/>
<key-property name="EffectiveDate" access="property"
column="EffDt" />
</composite-id>

Client:
<bag name="AccountTypeHistory" lazy="true">
<key>
<!-- a collection inherits the composite key type -->
<column name="ClientId"/>
<column name="EffectiveDate"/>
</key>
<one-to-many class="ClientAccountTypeHistoryItem"/>
</bag>

This should be pretty straight forward. Where I am going wrong?
Message has been deleted
Message has been deleted

epitka

unread,
Mar 16, 2009, 3:56:46 PM3/16/09
to nhusers
Ok I'll try to explain this little bit better. Basically I have two
tables (Client), that has surrogate PK key "ClientID" and Client has
natural key composed of ClientID and EffectiveDate.
How do I map a collection in Client that has all items for ClientID.

epitka

unread,
Mar 17, 2009, 9:00:28 AM3/17/09
to nhusers
Anybody???

Fabio Maulo

unread,
Mar 17, 2009, 9:40:33 AM3/17/09
to nhu...@googlegroups.com
as you can see many people don't like composite POID.

2009/3/17 epitka <exptra...@yahoo.com>



--
Fabio Maulo

epitka

unread,
Mar 17, 2009, 9:45:54 AM3/17/09
to nhusers
I don't like them either, but I am stuck with legacy db. If it was me
I would not event map it in a class as it is purely for reporting and
does not belong in domain at all. But higher powers want it mapped as
history field. So I tried all possible ways to map this and cannot get
it done. I've googled for two days, nothing. If I had any hair left I
would pull it out.

On Mar 17, 8:40 am, Fabio Maulo <fabioma...@gmail.com> wrote:
> as you can see many people don't like composite POID.
>
> 2009/3/17 epitka <exptrade2...@yahoo.com>

Oskar Berggren

unread,
Mar 17, 2009, 9:53:30 AM3/17/09
to nhu...@googlegroups.com
Have you tried using a <map>? With <key column="ClientId"/> and <index column="EffDt"/>.

/Oskar


2009/3/17 epitka <exptra...@yahoo.com>

epitka

unread,
Mar 17, 2009, 9:55:50 AM3/17/09
to nhusers
No, let me try that.

On Mar 17, 8:53 am, Oskar Berggren <oskar.bergg...@gmail.com> wrote:
> Have you tried using a <map>? With <key column="ClientId"/> and <index
> column="EffDt"/>.
>
> /Oskar
>
> 2009/3/17 epitka <exptrade2...@yahoo.com>

Oskar Berggren

unread,
Mar 17, 2009, 9:57:37 AM3/17/09
to nhu...@googlegroups.com
Another thing... The <key> clause in your bag I think should refer to the history items FOREIGN KEY pointing to the Clients PRIMARY KEY. So it should only contain the ClientId, not EffDt.

/Oskar


2009/3/17 epitka <exptra...@yahoo.com>

epitka

unread,
Mar 17, 2009, 10:09:30 AM3/17/09
to nhusers
Ok, I tried and I am getting error about no type specified

NHibernate.MappingException: No type name specified
at NHibernate.Mapping.SimpleValue.get_Type()
at NHibernate.Cfg.XmlHbmBinding.CollectionBinder.BindMapSecondPass
(XmlNode node, Map model, IDictionary`2 persistentClasses)
at
NHibernate.Cfg.XmlHbmBinding.CollectionBinder.<>c__DisplayClass4.<AddMapSecondPass>b__3
(IDictionary`2 persistentClasses)
at NHibernate.Cfg.Configuration.SecondPassCompile()
at NHibernate.Cfg.Configuration.BuildSessionFactory()


here is how I tried to map it in Client

<map name="AccountTypeHistory" access="nosetter.camelcase-underscore"
table="ClientAcctType">
<key column="ClientId"/>
<index column="EffDt"/>
<one-to-many
class="SR.Domain.Client.Values.ClientAccountTypeHistoryItem,
SR.Domain"/>
</map>

here is the history item mapping

<class name="SR.Domain.Client.Values.ClientAccountTypeHistoryItem,
SR.Domain"
table="ClientAcctType" lazy="true" >
<composite-id
class="SR.Domain.Client.Values.ClientAccountTypeCompositeID,
SR.Domain"
name="Id" access="nosetter.lowercase-underscore">
<key-property name="ClientID" column="ClientId" type="Int32"/>
<key-property name="EffectiveDate" column="EffDt"
type="DateTime" />
</composite-id>
</class>

On Mar 17, 8:53 am, Oskar Berggren <oskar.bergg...@gmail.com> wrote:
> Have you tried using a <map>? With <key column="ClientId"/> and <index
> column="EffDt"/>.
>
> /Oskar
>
> 2009/3/17 epitka <exptrade2...@yahoo.com>

Oskar Berggren

unread,
Mar 17, 2009, 10:23:49 AM3/17/09
to nhu...@googlegroups.com
Maybe you need to specify the type in the index tag?

Also, the table attribute on the map-element isn't used with one-to-many.

An alternative to using one-to-many may be composite-element, if this is the only place where the
ClientAccountTypeHistoryItem is mapped.

/Oskar



2009/3/17 epitka <exptra...@yahoo.com>

epitka

unread,
Mar 17, 2009, 10:35:05 AM3/17/09
to nhusers
Getting closer. When I have a map do I have to declare the property as
Dictionary or can List be used?
I get this now
NHibernate.MappingException: Error mapping generic collection
SR.Domain.Client.Entities.Client.AccountTypeHistory: expected 2
generic parameters, but the property type has 1
at NHibernate.Mapping.Collection.CheckGenericArgumentsLength(Int32
expectedLength)
at NHibernate.Mapping.Map.get_DefaultCollectionType()
at NHibernate.Mapping.Collection.get_CollectionType()

On Mar 17, 9:23 am, Oskar Berggren <oskar.bergg...@gmail.com> wrote:
> Maybe you need to specify the type in the index tag?
>
> Also, the table attribute on the map-element isn't used with one-to-many.
>
> An alternative to using one-to-many may be composite-element, if this is the
> only place where the ClientAccountTypeHistoryItem is mapped.
>
> /Oskar
>
> 2009/3/17 epitka <exptrade2...@yahoo.com>
>
>
>
> > Ok, I tried and I am getting error about no type specified
>
> >  NHibernate.MappingException: No type name specified
> >   at NHibernate.Mapping.SimpleValue.get_Type()
> >   at NHibernate.Cfg.XmlHbmBinding.CollectionBinder.BindMapSecondPass
> > (XmlNode node, Map model, IDictionary`2 persistentClasses)
> >   at
>
> > NHibernate.Cfg.XmlHbmBinding.CollectionBinder.<>c__DisplayClass4.<AddMapSec ondPass>b__3

epitka

unread,
Mar 17, 2009, 10:42:21 AM3/17/09
to nhusers
Thank you man, if you are in Dallas, I'll buy you a beer.


On Mar 17, 9:23 am, Oskar Berggren <oskar.bergg...@gmail.com> wrote:
> Maybe you need to specify the type in the index tag?
>
> Also, the table attribute on the map-element isn't used with one-to-many.
>
> An alternative to using one-to-many may be composite-element, if this is the
> only place where the ClientAccountTypeHistoryItem is mapped.
>
> /Oskar
>
> 2009/3/17 epitka <exptrade2...@yahoo.com>
>
>
>
> > Ok, I tried and I am getting error about no type specified
>
> >  NHibernate.MappingException: No type name specified
> >   at NHibernate.Mapping.SimpleValue.get_Type()
> >   at NHibernate.Cfg.XmlHbmBinding.CollectionBinder.BindMapSecondPass
> > (XmlNode node, Map model, IDictionary`2 persistentClasses)
> >   at
>
> > NHibernate.Cfg.XmlHbmBinding.CollectionBinder.<>c__DisplayClass4.<AddMapSec ondPass>b__3

Oskar Berggren

unread,
Mar 17, 2009, 11:10:07 AM3/17/09
to nhu...@googlegroups.com
Use IDictionary for your property I think. I'm not sure I've actually done this myself. :)

Im in Sweden so a bit far to go for a beer. :) But should I take your offer to mean that it is working now?

/Oskar


2009/3/17 epitka <exptra...@yahoo.com>

epitka

unread,
Mar 17, 2009, 11:17:41 AM3/17/09
to nhusers
Well if you come to Croatia for vacation, I can point you to some
people over there :)
Yes, I declared it as a dictionary and everything is working now.

On Mar 17, 10:10 am, Oskar Berggren <oskar.bergg...@gmail.com> wrote:
> Use IDictionary for your property I think. I'm not sure I've actually done
> this myself. :)
>
> Im in Sweden so a bit far to go for a beer. :) But should I take your offer
> to mean that it is working now?
>
> /Oskar
>
> 2009/3/17 epitka <exptrade2...@yahoo.com>
Reply all
Reply to author
Forward
0 new messages