Hi, I have inhertited an legacy application, that I have little control over. I need to map a one to one relationship because "A user may have one of these, lets call them 'a Rejection', but not more than one" The data stored in the Rejection table is quite large.
Anyway, I have simplyfied this model, using cats, dogs and an owner. An animal, by default, is stray (its owner object will be null), until we assign an owner. Cats and dogs are both animals. The classes look like this. By law, you are only allowed one Pet ;-)
public abstract class Entity {
public virtual int Id { get; set; }
}
public class Animal : Entity {
public virtual string Name { get; set; }
public virtual Owner Owner { get; set; }
}
public class Dog : Animal {
public virtual string Bark { get; set; }
}
public class Cat : Animal {
public virtual string Colour { get; set; }
}
public class Owner : Entity {
public virtual string Name { get; set; }
public virtual Animal Pet { get; set; }
}
And the mapping files for the Animal and Owner are like this:
public class OwnerMap : ClassMap<Owner> {
public OwnerMap() {
Id(x => x.Id).Column("animal_id");
Map(x => x.Name);
References(x => x.Pet, "animal_id").Cascade.SaveUpdate().ForeignKey();
}
}
public class AnimalMap : ClassMap<Animal> {
public AnimalMap() {
Id(x => x.Id).Column("animal_id");
Map(a => a.Name);
HasOne(x => x.Owner).PropertyRef(p => p.Pet).Cascade.All().Fetch.Join();
}
}
Now for the problem. I am able to insert the data into the database, and the sql generated by nhibernate is:
INSERT INTO [Animal] ([Name]) VALUES (@p0); select SCOPE_IDENTITY();@p0 = 'Odie'
INSERT INTO [Dog] ([Bark], [animal_id]) VALUES (@p0, @p1);@p0 = 'bark', @p1 = 1
INSERT INTO [Owner] ([Name], [animal_id]) VALUES (@p0, @p1); select SCOPE_IDENTITY();@p0 = 'Jon', @p1 = 1
The data does appear in the database, but then I get an error ' NHibernate.AssertionFailure: null identifier' after calling Session.save(animal) I think the problem is with the last bit of SQL "select SCOPE_IDENTITY()" which returns null. This is because the Owner Table primary key needs to come from the Animal Table.
Can anyone suggest how I could map this correctly in FNH? Any help appriciated. Dai
the table Schema
CREATE TABLE [dbo].[Animal](
[animal_id] [int] IDENTITY(1,1) NOT NULL,
[Name] [nvarchar](50) NULL,
CONSTRAINT [PK_Animal] PRIMARY KEY CLUSTERED ([animal_id] ASC )
WITH PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF,
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
ON [PRIMARY]) ON [PRIMARY]
CREATE TABLE [dbo].[Owner](
[animal_id] [int] NOT NULL,
[Name] [nvarchar](50) NULL, CONSTRAINT [PK_owner2]
PRIMARY KEY CLUSTERED (
[animal_id] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF,
IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
ON [PRIMARY] ) ON [PRIMARY]