当Id在抽象基类中时,NHibernate映射出现问题

时间:2011-04-11 20:25:45

标签: nhibernate loading base lazy-evaluation

我对nhibernate很新,我做得很好,直到我面对这个问题,它看起来像一个NHibernate的bug,但作为一个新手,它肯定是我的错

让这个基类完成所有Id和相等的东西

    public abstract class ObjetoConId
{
    public ObjetoConId()
    {
        Id=NewId();
    }

    public virtual Guid Id {get;private set;}

    public override bool Equals(object o)
    {
        if (Object.ReferenceEquals(this,o))
            return true;

        if (o==null) return false;

        ObjetoConId oId;

        oId= o as ObjetoConId;
        if (!Object.ReferenceEquals(oId,null))
            return (Id.Equals(oId.Id));

        return (base.Equals(o));
    }
    public override int GetHashCode()
    {
        byte[] bId;

        bId=Id.ToByteArray();

        return  ((Int32)(bId[8]^bId[12])<<24) +
                ((Int32)(bId[9]^bId[13])<<16) + 
                ((Int32)(bId[10]^bId[14])<<8) + 
                ((Int32)(bId[11]^bId[15]));
    }

    public virtual bool Equals(ObjetoConId o)
    {
        if (Object.ReferenceEquals(this,o))
            return true;

        if (Object.ReferenceEquals(o,null)) return false;
            return (Id.Equals(o.Id));
    }

    public virtual string toString() 
    {
        return this.GetType().FullName
        + "[id=" + Id + "]";
    }

    protected virtual Guid NewId()
    {
        return GuidComb.NewGuid();
    }

    public static bool operator == (ObjetoConId x,ObjetoConId y)
    {
        if(Object.ReferenceEquals(x,y))
            return true;
        if(Object.ReferenceEquals(x,null))
            return false;
        return x.Equals(y);
    }

    public static bool operator != (ObjetoConId x,ObjetoConId y)
    {
        return !(x==y);
    }

    /// <summary>
    /// Metodo interno para permitir el testing
    /// </summary>
    /// <param name="id"></param>
    internal void setId(Guid id)
    {
        Id=id;
    }
}

和这个实体

public class Propiedad : ObjetoConId,IPropiedad
{
    [Obsolete("Persistance Constructor only")]
    public Propiedad ()
    {
    }


    public Propiedad (IList<IDescripcionCalificada> descripciones)
    {
        Descripciones=new Dictionary<string,IDescripcionCalificada>(descripciones.Count);
        foreach(IDescripcionCalificada d in descripciones)
            Descripciones.Add(d.Nombre,d);
    }


    #region IPropiedad implementation
    public virtual IDictionary<string, IDescripcionCalificada> Descripciones {get;private set;}

    #endregion  

}

和这个映射

    public class MapeoPropiedad : ClassMap<Propiedad>
{ 
    public MapeoPropiedad()
    {
        Id(x => x.Id).Column("pro_id").GeneratedBy.Assigned();
        HasMany<DescripcionCalificada>(x => x.Descripciones)
        .Cascade.SaveUpdate()
        .AsMap<string>(index => index.Nombre)
        ;
    }
}

对它的测试是

[TestFixture]
public class TestPropiedadPersistencia
{

    [TestFixtureSetUp]
    public void TestFixtureSetUp()
    {

        string connectionString="Server=127.0.0.1;Database=Ana;User ID=dev-test;Password=dev-test;";

        fcfg=Fluently.Configure()
            .Database(PostgreSQLConfiguration.PostgreSQL82.ConnectionString(connectionString))
            .Mappings(m => m.FluentMappings.AddFromAssemblyOf<MapeoPropiedad>());


        fcfg.ExposeConfiguration(cfg => new SchemaExport(cfg).Create(false, true));
        sessions=fcfg.BuildSessionFactory();
    }


    ISessionFactory sessions;
    FluentConfiguration fcfg;



    [TestFixtureTearDown]
    public void TestFixtureTearDown()
    {
        fcfg.ExposeConfiguration(cfg => new SchemaExport(cfg).Drop(false, true));
        sessions.Close();
        sessions = null;
        fcfg = null;
    }


    [Test]
    public void CanCorrectlyMapPropiedad()
    {
        DescripcionCalificada descri1=new DescripcionCalificada("descri",new Descripcion("Esta es la descri"));
        DescripcionCalificada descri2=new DescripcionCalificada("descriLarga",new Descripcion("Esta es la descriLarga"));
        Dictionary<string,IDescripcionCalificada> descris=new Dictionary<string, IDescripcionCalificada>(2);

        descris.Add(descri1.Nombre,descri1);
        descris.Add(descri2.Nombre,descri2);

        new PersistenceSpecification<Propiedad>(sessions.OpenSession(),new CustomEqualityComparer() )
            .CheckProperty(c => c.Descripciones,descris)
            .VerifyTheMappings();
    }

}

问题是测试失败,除非我在映射中放入Not.LazyLoad() 它给出了映射错误

Ana.Nucleo.Lenguaje.Test.TestDescripcionCalificadaPersistencia (TestFixtureSetUp):
FluentNHibernate.Cfg.FluentConfigurationException : An invalid or incomplete configuration was used while creating a SessionFactory. Check PotentialReasons collection, and InnerException for more detail.


  ----> NHibernate.InvalidProxyTypeException : The following types may not be used as proxies:
Ana.Catalogacion.Implementacion.Propiedad: method setId should be 'public/protected virtual' or 'protected internal virtual'

没有延迟加载它传递,如果我将Id属性放在Propiedad类中而不是从ObjetoConID继承,它也会传递,有和没有Not.LazyLoad()。

任何人都可以确认这是一个NH病毒,或任何帮助将不胜感激

编辑:

我发现了问题,我的错。我错过了setId内部函数没有被虚拟保护并且与Id属性的setter混淆,因此误解了execption

费尔

1 个答案:

答案 0 :(得分:1)

我发现了问题,我的错。我错过了setId内部函数没有被虚拟保护并且与Id属性的setter混淆,因此误解了execption