Question

I've got two tables in database: Table A (parent) has a primary key column and Table B (child) doesn't have a key at all, but references to the key in table A (parent).

The column aID (not a primary/foreign key) refererences to the id in table A (parent).

image

I've tried to use a composite key in table B, but without any success:

Mappings:

 public AMap() 
 {
    Id(a=> a.Id);
    Map(a=> a.Name);
    HasMany(a=> a.B)
       .Cascade.All();
 }

 public BMap() 
 {
    CompositeId()
       .KeyReference(b=> b.A, "aID");
    Map(b=> b.Name);
    Map(b=> b.Year);
 }

Entity A properties:

 public virtual int Id { get; set; }
 public virtual string Name { get; set; }
 public virtual IList<B> B { get; set; }

Entity B properties:

    public virtual A A { get; set; }
    public virtual string Name { get; set; }
    public virtual string Year { get; set; }

I've also tried components:

 public AMap() 
 {
    HasMany<B>(a => a.B)
        .Component(b =>
        {
           b.References<A>(bb=> bb.A).Fetch.Join();
         //b.Map(bb => bb.A).Column("aID");
           b.Map(bb => bb.Name);
           b.Map(bb => bb.Year);
        })
        .Inverse()
        .Cascade.All();
 }

But then i get following exceptions:

Inner exception: NHibernate.MappingException: Repeated column in mapping for collection: TestProject.Test.A.B column: A_id

The B list does not get populated when im getting all a:s from database, does anyone see something wrong in this code or have a better solution than using a Composite key ? Is it possible to let nhibernate use an identifier only in application layer ? I'm not able to change data model in database.

EDIT: Added new exception occured, changed to auto properties.

Was it helpful?

Solution 3

Finally solved it with:

 public AMap() 
 {
    ....
    ....
    HasMany(a=> a.B).KeyColumn("aID").Inverse().Cascade.All();
 }

 public BMap()
 {
   CompositeId()
         .KeyProperty(b=> b.AID)
         .KeyProperty(b=> b.Name)
         .KeyProperty(b=> b.Year);
   References(b=> b.A).Column("aID");
   Map(b=> b.Name);
   Map(b=> b.Year);
 }

OTHER TIPS

You should use a component but , you should use a collection of components. See : component collection mapping NHibernate 3.2

You should drop the AID property from Entity B and just use:

public BMap() 
{
    Map(b=> b.Name);
    Map(b=> b.Year);
    References(b => b.A).Column("aID");
}

See here for more information.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top