Компоненты NHibernate не сохраняются? - PullRequest
0 голосов
/ 02 декабря 2011

Я использую 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 голосов
/ 07 декабря 2011

хорошо, это не имеет ничего общего с отображением.сопоставление верно!

это сбой Spring Transaction, не уверен, что это моя ошибка при настройке Spring.Net SessionFactory.

Обходной путь заключается в явном вызове:

Session.Flush();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...