NHibernate.MappingException: Sin persistencia para: XYZ

134

Ahora, antes de decirlo: hice Google y mi hbm.xmlarchivo es un recurso incrustado.

Aquí está el código que estoy llamando:

ISession session = GetCurrentSession();
var returnObject =  session.Get<T>(Id);

Aquí está mi archivo de mapeo para la clase:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
  <class name="HQData.Objects.SubCategory, HQData" table="SubCategory" lazy="true">
    <id name="ID" column="ID" unsaved-value="0">
      <generator class="identity" />
    </id>

    <property name="Name" column="Name" />
    <property name="NumberOfBuckets" column="NumberOfBuckets"  />
    <property name="SearchCriteriaOne" column="SearchCriteriaOne" />

    <bag name="_Businesses" cascade="all">
      <key column="SubCategoryId"/>
      <one-to-many 
         class="HQData.Objects.Business, HQData"/>
    </bag>

    <bag name="_Buckets" cascade="all">
      <key column="SubCategoryId"/>
      <one-to-many
         class="HQData.Objects.Bucket, HQData"/>
    </bag>

  </class>
</hibernate-mapping>

¿Alguien ha tenido este problema antes?

Aquí está el mensaje de error completo:

MappingException: No persiste para: HQData.Objects.SubCategory] NHibernate.Impl.SessionFactoryImpl.GetEntityPersister (String entityName, Boolean throwIfNotFound)
 en c: \ CSharp \ NH2.0.0 \ nhibernate \ src \ NHibernate \ Impl \ SessionFactoryImpl.cs: 766 NHibernate.Impl.SessionFactoryImpl.GetEntityPersister (String entityName)
 en c: \ CSharp \ NH2.0.0 \ nhibernate \ src \ NHibernate \ Impl \ SessionFactoryImpl.cs: 752 NHibernate.Event.Default.DefaultLoadEventListener.OnLoad (evento LoadEvent, LoadType loadType)
 en c: \ CSharp \ NH2.0.0 \ nhibernate \ src \ NHibernate \ Event \ Default \ DefaultLoadEventListener.cs: 37 NHibernate.Impl.SessionImpl.FireLoad (evento LoadEvent, LoadType loadType)
 en c: \ CSharp \ NH2.0.0 \ nhibernate \ src \ NHibernate \ Impl \ SessionImpl.cs: 2054 NHibernate.Impl.SessionImpl.Get (String entityName, Object id)
 en c: \ CSharp \ NH2.0.0 \ nhibernate \ src \ NHibernate \ Impl \ SessionImpl.cs: 1029 NHibernate.Impl.SessionImpl.Get (Tipo entityClass, Object id)
 en c: \ CSharp \ NH2.0.0 \ nhibernate \ src \ NHibernate \ Impl \ SessionImpl.cs: 1020 NHibernate.Impl.SessionImpl.Get (Id. de objeto)
 en c: \ CSharp \ NH2.0.0 \ nhibernate \ src \ NHibernate \ Impl \ SessionImpl.cs: 985 HQData.DataAccessUtils.NHibernateObjectHelper.LoadDataObject (Int32 Id)
 en C: \ Development \ HQChannelRepo \ HQ Channel Application \ HQChannel \ HQData \ DataAccessUtils \ NHibernateObjectHelper.cs: 42 HQWebsite.LocalSearch.get_subCategory ()
 en C: \ Development \ HQChannelRepo \ HQ Channel Application \ HQChannel \ HQWebsite \ LocalSearch.aspx.cs: 17 HQWebsite.LocalSearch.Page_Load (remitente de objetos, EventArgs e)
 en C: \ Development \ HQChannelRepo \ HQ Channel Application \ HQChannel \ HQWebsite \ LocalSearch.aspx.cs: 27 System.Web.Util.CalliHelper.EventArgFunctionCaller (IntPtr fp, Object o, Object t, EventArgs e) +15 System.Web .Util.CalliEventHandlerDelegateProxy.Callback (Remitente de objetos, EventArgs e) +33 System.Web.UI.Control.OnLoad (EventArgs e) +99 System.Web.UI.Control.LoadRecursive () +47 System.Web.UI.Page .ProcessRequestMain (Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +1436

Actualización , esta es la solución para mi escenario: había cambiado algo de código y no estaba agregando el ensamblado al archivo de configuración durante el tiempo de ejecución.

Sara Chipps
fuente
Tuve el mismo error, pero un problema diferente. Session.Load ("SearchItem", searchItemID) ya que SearchItem devuelve un error de asignación, Session.Load <SearchItem> (searchItemID) no lo hace (y es una forma menos propensa a errores de hacerlo de todos modos.)
Kendrick

Respuestas:

101

Parece que olvidó agregar un ensamblaje de mapeo a la configuración de fábrica de la sesión.

Si está utilizando app.config ...

.
.
    <property name="show_sql">true</property>
    <property name="query.substitutions">true 1, false 0, yes 'Y', no 'N'</property>
    <mapping assembly="Project.DomainModel"/>  <!-- Here -->
</session-factory>
.
.
Andy S
fuente
77
¿Cómo hacer esto en NHibernate fluido? Estoy desarrollando un patrón en un proyecto separado, por lo que no tengo acceso al ensamblaje del usuario.
Mustafa Magdy
Si no puede hacer referencia al ensamblaje del usuario, no creo que pueda usar NHibernate fluido.
Andy S
91

Algo obvio, pero bastante útil para alguien nuevo en NHibernate.

Todos los archivos de mapeo XML deben tratarse como recursos integrados en lugar del contenido predeterminado . Esta opción se establece editando el atributo Build Action en las propiedades del archivo.

Los archivos XML se incrustan en el ensamblaje y se analizan al inicio del proyecto durante la fase de configuración de NHibernate.

Chris Vosnidis
fuente
1
Aleluya, lo tengo como un Embedded resource, pero cuando lo copié de una computadora a otra, el archivo perdió esta propiedad. Me rasqué la cabeza por un par de buenos minutos.
Dragos Durlut
1
@DragosDurlut el archivo del proyecto (.csproj) que guarda la información de los archivos del proyecto, no el archivo en sí.
Wagner Leonardi
50

Mi problema fue que olvidé poner el .hbm en el nombre del mapeo xml. ¡También asegúrese de convertirlo en un recurso incrustado!

nHibernate User
fuente
1
¡Ese fue mi error también!
Gringo
Este también fue mi problema, obtengo el mismo error que en Q al hacer get. Al intentar consultar todos los objetos de ese tipo, no hay error, ¡solo un conjunto de resultados vacío!
Christoph
Arg: olvidé el .hbm también. ¡Gracias!
Dr. C. Hilarius
42

Saqué esto de aquí :

En mi caso, la clase de mapeo no era pública. En otras palabras, en lugar de:

public class UserMap : ClassMap<user>  // note the public!

Acabo de tener:

class UserMap : ClassMap<user>
basarat
fuente
Gracias, me salvaste de un poco de dolor de cabeza. :)
Rytmis
2
Si usa Fluent, diría que esta sería la causa más común. Gracias, eso fue muy fácil de perder.
Richard Neil Ilagan
1
¡Gracias! Al comprobar si había hecho públicas mis clases de mapeo o no, descubrí que no había escrito una clase de mapeo para esta entidad, ¡vaya! :) Me ahorró un montón de tiempo!
Jen
28

Pasando unas 4 horas buscando en Google y desbordando la pila , probando todas las cosas por ahí, he encontrado mi error:

Mi archivo de mapeo se llamaba .nbm.xml en lugar de .hbm.xml . Eso fue una locura.

Nickmaovich
fuente
9
Argh, acabo de hacer lo mismo, excepto que lo tenía como .xml en lugar de .hbm.xml. Tal vez debería haber algunas pistas en los errores :)
Rezler
2
Dios mio. No puedo creer que hice esto. Estaba buscando horas en los archivos de mapeo de errores y resultó que había cometido un error tipográfico en el nombre de archivo ... doh. ¡Gracias! Me estremezco al pensar cuánto tiempo habría estado arrancándome el pelo si no me hubiera topado con esto.
Kamui
1
Wow, gran captura: me estaba sacando el pelo por este problema. Revisé mi archivo xml cientos de veces y no pude entender por qué no funcionaba como los demás. En realidad me faltaba la parte ".hbm" del nombre del archivo. ¡Gracias!
Extremo
Me salvaste las horas. Gracias
Manjay_TBAG
4

Tuve un problema similar y lo resolví de la siguiente manera:

Estaba trabajando en MS SQL 2008, pero en la configuración de NH tenía un mal dialecto: NHibernate.Dialect. MsSql2005Dialect si lo corrijo a: NHibernate.Dialect. MsSql2008Dialect entonces todo funciona bien sin una excepción "No persistir para: ..." David.

David
fuente
3

También estaba agregando el ensamblaje incorrecto durante la inicialización. La clase que persisto está en el ensamblado n. ° 1, y mi archivo .hbm.xml está incrustado en el ensamblaje n. ° 2. Cambié cfg.AddAssembly(...para agregar el ensamblaje # 2 (en lugar del ensamblaje # 1) y todo funcionó. ¡Gracias!

Seth
fuente
3

Para agregar a la respuesta de Amol, no cometa el error de especificar el tipo de clase de interfaz. Asegúrese de especificar la clase de implementación . (Es decir, no use IDomainObjectType). No es que haya cometido este error ... :)

goku_da_master
fuente
2

Debe ser name="Id"? Los errores tipográficos son una causa probable.

Lo siguiente sería probarlo con una prueba no genérica para asegurarse de que está pasando el parámetro de tipo adecuado.

¿Puedes publicar el mensaje de error completo?

Matt Hinze
fuente
2

Tuve el mismo problema porque estaba agregando el ensamblaje incorrecto en el método Configuration.AddAssembly ().

IdontCareAboutReputationPoints
fuente
2

Este error ocurre debido a una configuración de mapeo no válida. Debe verificar dónde establece .Mapas para su fábrica de sesiones. Básicamente busque ".Mappings (" en su proyecto y asegúrese de haber especificado la clase de entidad correcta en la línea siguiente.

.Mappings(m => m.FluentMappings.AddFromAssemblyOf<YourEntityClassName>())
Arkadas Kilic
fuente
gracias amigo! ¡Cambié el proyecto en el que estaban sentadas mis entidades!
viggity
1

Si ejecuta pruebas en el repositorio desde un ensamblaje separado, asegúrese de que su Hibernate.cfg.xml esté configurado para salir siempre en el directorio bin de dicho ensamblaje. Esto no sucedía para nosotros y obtuvimos el error anterior en ciertas circunstancias.

Descargo de responsabilidad: este podría ser un consejo un poco esotérico, dado que es un resultado directo de cómo estructuramos nuestros conjuntos de prueba de integración de repositorio (es decir, tenemos un enlace simbólico de cada conjunto de prueba a un solo Hibernate.xfg.xml)


fuente
1

No olvide especificar información de mapeo en el archivo .config

p.ej

donde MyApp.Data es un ensamblado que contiene sus asignaciones


fuente
0

Tuve un problema similar al encontrar un objeto por id ... Todo lo que hice fue usar el nombre completo en el nombre de la clase. Eso es antes de que fuera:

find("Class",id)

Objeto por lo que se convirtió así:

find("assemblyName.Class",id)
Jeff Atwood
fuente
0

Asegúrese de haber llamado al CreateCriteria(typeof(DomainObjectType))método en la sesión para el objeto de dominio que intenta obtener de DB.

Amol
fuente
Esto es persistente, no una búsqueda.
Joshua Drake
0

Tengo un problema similar pero se cumplen todos los requisitos mencionados . En mi caso, intento guardar alguna clase de entidad (Tipo de OBJEKTE) en la base de datos. Otros lugares funcionan, pero solo en este caso falla y genera esta excepción.

Mi solución (HACK) fue volver a mapear el objeto de tipo OBJEKTE nuevamente y almacenarlo luego. De repente funciona. Pero no preguntes por qué.

            OBJEKTE t = _mapper.Map<OBJEKTE>(inparam);
            OBJEKTE res = await _objRepo.UpdateAsync(t);

Si inparam iría directamente a UpdateAsync (), no puede encontrar un persistente coincidente.

Podría explicarse por la forma en que NH hace esto. Deriva un proxy de su clase de mapeo e implementa las propiedades con manejo sucio incluido. Mira esto:

t.GetType()
{Name = "OBJEKTE" FullName = "MyComp.Persistence.OBJEKTE"}

inparam.GetType()
{Name = "OBJEKTEProxyForFieldInterceptor" FullName = "OBJEKTEProxyForFieldInterceptor"}

Sin embargo, lo divertido es que la fuente de inparamhecho es el repositorio NH en sí. De todos modos Me quedo con este truco de reasignación para la próxima vez.

Robetto
fuente