Repeated column in mapping for collection - fluent-nhibernate

I have a Mapping file of Table XX with composite key XX_ID and A_ID
class XX
{
CompositeId()
.KeyProperty(x => x.Id, "XX_ID")
.KeyReference(x => x.A, "A_ID");
}
Having Another Table YY with Composite key YY_ID and A_ID.
class YY
{
CompositeId()
.KeyProperty(x => x.Id, "YY_ID")
.KeyReference(x => x.A, "A_ID");
}
Now I am Creating many-To-many relationship in between XX and YY with common table XX_YY in Table XX so Class XX is written Like this.
class XX
{
CompositeId()
.KeyProperty(x => x.Id, "XX_ID")
.KeyReference(x => x.A, "A_ID");
HasManyToMany(x => x.XXList)
.Table("XX_YY")
.ParentKeyColumns.Add("XX_ID", "A_ID")
.ChildKeyColumns.Add("YY_ID", "A_ID")
.Cascade.All()
.LazyLoad();
}
its giving me Error:-
Repeated column in mapping for collection: XX column: A_ID

Related

Fluent NHibernate error: Must have same number of columns as the referenced primary key

I am new with Fluent NHibernate and I have a problem with a particular HasMany relationship.
I have three objects: User, Company and CompanyAddress
User references Company correctly and Company would reference CompanyAddress (but this fails).
Company mapping is composed like following:
public class CompanyMap : ClassMap<Company>
{
public CompanyMap()
{
Schema("company");
Table("LIST");
this.CompositeId(x => x.key)
.KeyProperty(x => x.applicationId, "APPLICATION_ID")
.KeyProperty(x => x.id, "ID")
.KeyProperty(x => x.userId, "USER_ID");
this.Map(x => x.vat, "VAT");
this.HasMany(x => x.addresses)
.Not.LazyLoad()
.Cascade.None();
this.References(x => x.user)
.Class<User>()
.Columns("APPLICATION_ID", "USER_ID")
.Insert()
.Update()
.Fetch.Select()
.Not.LazyLoad()
.Cascade.None();
}
}
and CompanyAddress is:
public class CompanyAddressMap : ClassMap<CompanyAddress>
{
public CompanyAddressMap()
{
Schema("[address]");
Table("COMPANY_LIST");
this.CompositeId(x => x.key)
.KeyProperty(x => x.applicationId, "APPLICATION_ID")
.KeyProperty(x => x.id, "ID")
.KeyProperty(x => x.entityId, "COMPANY_ID");
this.Map(x => x.country, "COUNTRY");
this.Map(x => x.province, "PROVINCE");
this.Map(x => x.region, "REGION");
this.Map(x => x.city, "CITY");
this.Map(x => x.address, "[ADDRESS]");
this.Map(x => x.description, "DESCRIPTION");
this.References(x => x.company)
.Class<Company>()
.Columns("APPLICATION_ID", "COMPANY_ID")
.Insert()
.Update()
.Fetch.Select()
.Not.LazyLoad()
.Cascade.None();
}
}
but I receive this error:
Foreign key (FK8DE1BC098F20893F:COMPANY_LIST [APPLICATION_ID, COMPANY_ID])) must have same number of columns as the referenced primary key (LIST [APPLICATION_ID, ID, USER_ID])
I need to reference AddressCompany with non primary key because Company is already referenced by User and so my question is:
How can I reference this foreign key using Fluent NHibernate without modifying the real foreign key defined into the database?
[EDIT]
i need to reference AddressCompany with non the primary key 'cause Company is already referenced by User and so my question is: how can i reference this foreign key using fluent nhibernate without modifying the real foreign key defined into the database?
i don't want to add USER_ID field to the [address].[COMPANY_LIST] table and i don't want to add userId field to AddressCompany class... 'cause is a useless field... the relationships are:
user.LIST
applicationId (pk)
id (pk)
company.LIST
applicationId (pk) (fk -> user.LIST(applicationId))
id (pk)
userId (pk) (fk -> user.LIST(id))
address.COMPANY_LIST
applicationId (pk) (fk -> company.LIST(applicationId))
id (pk)
companyId (pk) (fk -> company.LIST(id))
why nhibernate wants force me to reference only the exact primary key?
could i reference a subset of the primary key of Company class?
thanks so much...
The error seems pretty self evident from your mapping and error message
Foreign key (FK8DE1BC098F20893F:COMPANY_LIST [APPLICATION_ID,
COMPANY_ID])) must have same number of columns as the referenced
primary key (LIST [APPLICATION_ID, ID, USER_ID])
You mappings for CompanyMap maps your primary key for as three columns
this.CompositeId(x => x.key)
.KeyProperty(x => x.applicationId, "APPLICATION_ID")
.KeyProperty(x => x.id, "ID")
.KeyProperty(x => x.userId, "USER_ID");
but your references to Company in CompanyAddressMap only maps back to Company with 2 columns
this.References(x => x.company)
.Class<Company>()
.Columns("APPLICATION_ID", "COMPANY_ID")
.Insert()
.Update()
.Fetch.Select()
.Not.LazyLoad()
.Cascade.None();
Add the ID column to your columns listing.

Sharing field as composite key and foreign key in Fluent NHibernate

Consider following mapping code please :
public sealed class BankMapping : ClassMap<Bank>
{
public BankMapping()
{
CompositeId()
.KeyProperty(x => x.SerialNumber, "SerialBankRef")
.KeyProperty(x => x.FinancialPeriodId, "FinancialPeriodRef");
Map(x => x.Code);
Map(x => x.Title);
Map(x => x.Comment);
Map(x => x.IsActive);
HasMany(x => x.BankBranchs).KeyColumns.Add(new[] { "SerialBankRef", "FinancialPeriodRef" });
}
}
And the BankBranch mapping code is :
public sealed class BankBranchMapping : ClassMap<BankBranch>
{
public BankBranchMapping()
{
CompositeId()
.KeyProperty(x => x.FinancialPeriodId, "FinancialPeriodRef")
.KeyProperty(x => x.SerialNumber, "SerialNumber");
Map(x => x.Code);
Map(x => x.Title);
Map(x => x.Comment);
Map(x => x.IsActive);
Map(x => x.Address);
Map(x => x.Fax);
Map(x => x.Telephone);
References(x => x.Bank).Columns(new[] { "SerialBankRef", "FinancialPeriodRef" });
}
}
As you can see the FinancialPeriodRef field acts as foreign key and part of composite key in the BankBranch mapping and NHibernate builds DB correctly and everything seems to be fine until I try to insert a record in the BankBranch table.
The error System.IndexOutOfRangeException : Invalid index 10 for this SqlParameterCollection with Count=10. which indicates I've mapped a field (FinancialPeriodRef) twice as FK and PK appears and I have no idea how to fix the problem.
I need FinancialPeriodRef in the BankBranch as part of primary key while it's absolutely equal to FinancialPeriodRef from Bank.
I need this field to establish unique constraint and also benefits of composite key is essential.
You need to use KeyReference rather than KeyProperty to describe composite foreign keys.
public BankBranchMapping()
{
CompositeId()
.KeyReference(x => x.FinancialPeriodId, "FinancialPeriodRef")
.KeyReference(x => x.SerialNumber, "SerialNumber");
...
}
I had the exact same problem as you and after an hour or so came across this post: https://stackoverflow.com/a/7997225/569662 which pointed me right.

Fluent NHibernate misplaced duplicate field

I think I'm misunderstanding something about how this works. This is my fluent mapping:
public class FunctionInfoMap : ClassMap<FunctionInfo>
{
public FunctionInfoMap()
{
Id(x => x.Id);
Map(x => x.Name);
Map(x => x.Signature);
Map(x => x.IsNative);
Map(x => x.ClassId);
References(x => x.Class, "ClassId");
HasMany(x => x.CallsAsParent).Inverse();
HasMany(x => x.CallsAsChild).Inverse();
Table("Functions");
}
}
public class CallMap : ClassMap<Call>
{
public CallMap()
{
CompositeId()
.KeyProperty(x => x.ThreadId)
.KeyProperty(x => x.ParentId)
.KeyProperty(x => x.ChildId)
.Mapped();
Map(x => x.ThreadId).Index("Calls_ThreadIndex");
Map(x => x.ParentId).Index("Calls_ParentIndex");
Map(x => x.ChildId).Index("Calls_ChildIndex");
Map(x => x.HitCount);
References(x => x.Thread, "ThreadId");
References(x => x.Parent, "ParentId");
References(x => x.Child, "ChildId");
Table("Calls");
}
}
public class SampleMap : ClassMap<Sample>
{
public SampleMap()
{
CompositeId()
.KeyProperty(x => x.ThreadId)
.KeyProperty(x => x.FunctionId)
.Mapped();
Map(x => x.ThreadId);
Map(x => x.FunctionId);
Map(x => x.HitCount);
References(x => x.Thread, "ThreadId");
References(x => x.Function, "FunctionId");
Table("Samples");
}
}
Now when I create this schema into a fresh database, that FunctionId field from SampleMap winds up in the Calls table.
create table Calls (
ThreadId INTEGER not null,
ParentId INTEGER not null,
ChildId INTEGER not null,
HitCount INTEGER,
FunctionId INTEGER,
primary key (ThreadId, ParentId, ChildId)
)
create table Samples (
ThreadId INTEGER not null,
FunctionId INTEGER not null,
HitCount INTEGER,
FunctionId INTEGER,
primary key (ThreadId, FunctionId)
)
I don't understand why it's there, since it should only exist in the Samples table.
You should not map both the foreign key and the many-ton-one relationship. Instead of
Map(x => x.ThreadId).Index("Calls_ThreadIndex");
Map(x => x.ParentId).Index("Calls_ParentIndex");
Map(x => x.ChildId).Index("Calls_ChildIndex");
Map(x => x.HitCount);
References(x => x.Thread, "ThreadId");
References(x => x.Parent, "ParentId");
References(x => x.Child, "ChildId");
map the many-to-ones which use the foreign keys
Map(x => x.HitCount);
References(x => x.Thread, "ThreadId");
References(x => x.Parent, "ParentId");
References(x => x.Child, "ChildId");
I don't know if this will solve your problem. Also, I strongly advise against using composite keys. Replace them with surrogate key (identity) and unique indexes.
I finally figured out the problem, more or less. The pair of collections on FunctionInfoMap were confusing NHibernate, since they don't actually lead anywhere. Adding KeyColumn entries to link them up to the Parent and Child associations corrected the stray field.

Abort due to constraint violation columns GroupId, idx are not unique

I'm using FluentNHibernate and have done a many-to-many mapping but when I try to save my entity I get the following error:
NHibernate.Exceptions.GenericADOException: NHibernate.Exceptions.GenericADOException
: could not insert collection: [Test.Entities.Recipient.Groups#b6815d34-f436-4142-9b8e-1bfcbf25509e][SQL: SQL not available]
---- System.Data.SQLite.SQLiteException : Abort due to constraint violation
columns GroupId, idx are not unique
Here is my mapping:
public class GroupMap : ClassMap<Group>
{
public GroupMap()
{
Id(x => x.Id).GeneratedBy.Guid();
Map(x => x.Name);
Map(x => x.SenderName);
Map(x => x.Created);
HasManyToMany(x => x.Recipients)
.AsList()
.WithTableName("groups_recipients")
.WithParentKeyColumn("GroupId")
.WithChildKeyColumn("RecipientId")
.LazyLoad()
.Cascade.AllDeleteOrphan();
}
}
public class RecipientMap : ClassMap<Recipient>
{
public RecipientMap()
{
Id(x => x.Id).GeneratedBy.Guid();
Map(x => x.Firstname);
Map(x => x.Lastname);
Map(x => x.Phone);
Map(x => x.Email);
HasManyToMany(x => x.Groups)
.AsList()
.WithTableName("groups_recipients")
.WithParentKeyColumn("RecipientId")
.WithChildKeyColumn("GroupId")
.LazyLoad().Cascade.None();
}
}
The problem seems to have something to do with the relationship tables id but I can't figure out how to solve it.
Cheers,
nandarya
Using AsList() was not a good idea. Should be AsBag(). And everything seems to work.

Fluent Nhibernate composed entity, specify foreign key

I have a Fluent Nhibernate map like :
public class UserMap : ClassMap<PortalUser>
{
public UserMap()
{
WithTable("aspnet_Users");
Id(x => x.Id, "UserId")
.GeneratedBy.Guid();
Map(x => x.Name, "UserName");
Map(x => x.Login, "LoweredUserName");
WithTable("LdapUsers", m => m.Map(x => x.FullName, "FullName"));
}
}
My foreign key column in table "LdapUser" is UserId but the select that gets generated is going to look for a "PortalUserId".
Is there a way to specify the relation key direcly?
Try this:
...
WithTable("LdapUsers", m => {
m.Map(x => x.FullName, "FullName");
m.WithKeyColumn("UserId");
});