NHibernate组件没有保存?

时间:2011-12-02 15:06:59

标签: nhibernate

我正在使用Nhibernate 3.2 GA,我正在按代码进行映射。

我有一个带有2个组件的简单类:

 public class Organization : EntityBase
{
    public Organization() 
    {
        Users = new List<User>();
        BankAccounts = new List<BankAccount>();
    }

    [Required]
    public virtual Guid ExternalID { set; get; }

    [Required]
    public virtual Int64 Number { set; get; }

    [Required]
    public virtual string Name { set; get; }

    public virtual Person Contact { set; get; }

    public virtual Address Address { set; get; }

    [Required]
    [DataType(DataType.EmailAddress)]
    public virtual string Email { set; get; }

    [DataType(DataType.Url)]
    public virtual string Website { set; get; }

    public virtual IList<BankAccount> BankAccounts { set; get; }

    public virtual IList<User> Users { set; get; }

}

实体在没有组件的情况下成功保存。

然而,当我检索实体并尝试更新组件时,没有真正发生的事情!

这是映射代码:

    var mapper = new ConventionModelMapper();

var entityBaseType = typeof(EntityBase);

// define root entity and ignore base from being mapped.
mapper.IsEntity((t, declared) => entityBaseType.IsAssignableFrom(t) && !t.IsInterface && !t.IsAbstract);

mapper.IsRootEntity((t, declared) => entityBaseType.Equals(t.BaseType)
                                     || t.BaseType == typeof(InvoiceBase) 
                                     || t.BaseType == typeof(InvoiceItemBase));

mapper.IsComponent((t, declared) => t.Namespace.EndsWith("Components"));

// column naming and cascading configuration 
mapper.BeforeMapManyToOne += (insp, prop, map) => map.Column(prop.LocalMember.GetPropertyOrFieldType().Name + "Id");
mapper.BeforeMapManyToOne += (insp, prop, map) => map.Cascade(Cascade.Persist);
mapper.BeforeMapBag += (insp, prop, map) => map.Key(km => km.Column(prop.GetContainerEntity(insp).Name + "Id"));
mapper.BeforeMapBag += (insp, prop, map) => map.Cascade(Cascade.All);

// enitity class mapping
mapper.Class<EntityBase>(map => {

    map.Id(e => e.ID, m => m.Generator(Generators.Identity));

    map.Property(e => e.CreatedOn);
    map.Property(e => e.DeletedOn);
    map.Property(e => e.UpdatedOn);

    map.ManyToOne<User>(e => e.CreatedBy, m => { m.Column("CreatedBy"); });
    map.ManyToOne<User>(e => e.DeletedBy, m => { m.Column("DeletedBy"); });
    map.ManyToOne<User>(e => e.UpdateBy, m => { m.Column("UpdateBy"); });

});


//define components 
mapper.Component<Person>(map => {

    map.Property(p => p.Email, m => m.Column("Preson_Email"));
    map.Property(p => p.Name, m => m.Column("Preson_Name"));
    map.Property(p => p.Surname, m => m.Column("Preson_Surname"));

    map.Insert(true);
    map.Update(true);

});

mapper.Component<Address>(map => {

    map.Property(a => a.City, m => m.Column("Address_City"));
    map.Property(a => a.Street, m => m.Column("Address_Street"));
    map.Property(a => a.Zipcode, m => m.Column("Address_Zipcode"));

    map.Insert(true);
    map.Update(true);

});

//TODO: move to different class (cleaner)
//all entities mapping
mapper.Class<User>(map => {
    map.ManyToOne(u => u.Organization);
});

mapper.Class<Organization>(map => {

    map.Component<Person>(o => o.Contact);
    map.Component<Address>(o => o.Address);

    map.Bag<User>(o => o.Users, cm => cm.Inverse(true), r => { });
});

var mapping = mapper.CompileMappingFor(entityBaseType.Assembly.GetExportedTypes().Where(t => t.Namespace.EndsWith("Domain")));

以下是我如何保存到数据库:

// get user domain object
                var user = UserService.GetById((int)membershipUser.ProviderUserKey);
                // get the organization to continue the profile
                var organization = OrganizationService.GetByExternalId(model.ExternalID);

                organization.Address = new Address
                    {
                        City = model.OrganizationAddressCity,
                        Street = model.OrganizationAddressStreet,
                        Zipcode = model.OrganizationAddressZip
                    };

                organization.Contact = new Person
                    {
                        Email = model.OrganizationContactEmail,
                        Name = model.OrganizationContactName,
                        Surname = model.OrganizationContactSurname
                    };

                  //organization.CreatedBy = user;
                  organization.UpdatedOn = DateTime.Now;

                 // add the user to the organization
                  organization.Users.Add(user);

                //save organization profile
                OrganizationService.Update(organization);

使用Spring.Net事务管理的组织存储库:

        [Transaction]
    public virtual void Update(T entity)
    {
        entity.UpdatedOn = DateTime.Now;
        Session.Update(entity);
    }

注意:使用Spring.Net事务管理修饰的方法,所以我没有显式调用Commit。

1 个答案:

答案 0 :(得分:0)

好的,它与映射无关。映射是正确的!

这是Spring Transaction的故障,不确定是否是我配置Spring.Net SessionFactory的错误。

解决方法是明确调用:

Session.Flush();