Closed
Description
It seems that there is a problem with one-to-one relations or my mapping.
Exception:
Exception occurred getter of TestNhBug.FileEntry.Id
NHibernate.PropertyAccessException: Exception occurred getter of TestNhBug.FileEntry.Id ---> System.Reflection.TargetException: Non-static method requires a target.
at System.Reflection.RuntimeMethodInfo.CheckConsistency(Object target)
at System.Reflection.RuntimeMethodInfo.InvokeArgumentsCheck(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.Reflection.RuntimePropertyInfo.GetValue(Object obj, Object[] index)
at NHibernate.Properties.BasicPropertyAccessor.BasicGetter.Get(Object target)
--- End of inner exception stack trace ---
at NHibernate.Properties.BasicPropertyAccessor.BasicGetter.Get(Object target)
at NHibernate.Tuple.Entity.AbstractEntityTuplizer.GetIdentifier(Object entity)
at NHibernate.Persister.Entity.AbstractEntityPersister.IsTransient(Object entity, ISessionImplementor session)
at NHibernate.Engine.ForeignKeys.IsTransientFast(String entityName, Object entity, ISessionImplementor session)
at NHibernate.Engine.ForeignKeys.IsTransientSlow(String entityName, Object entity, ISessionImplementor session)
at NHibernate.Event.Default.DefaultDeleteEventListener.OnDelete(DeleteEvent event, ISet`1 transientEntities)
at NHibernate.Impl.SessionImpl.FireDelete(DeleteEvent event, ISet`1 transientEntities)
at NHibernate.Impl.SessionImpl.Delete(String entityName, Object child, Boolean isCascadeDeleteEnabled, ISet`1 transientEntities)
at NHibernate.Engine.Cascade.CascadeOn(IEntityPersister persister, Object parent, Object anything)
at NHibernate.Event.Default.AbstractFlushingEventListener.CascadeOnFlush(IEventSource session, IEntityPersister persister, Object key, Object anything)
at NHibernate.Event.Default.AbstractFlushingEventListener.PrepareEntityFlushes(IEventSource session)
at NHibernate.Event.Default.AbstractFlushingEventListener.FlushEverythingToExecutions(FlushEvent event)
at NHibernate.Event.Default.DefaultAutoFlushEventListener.OnAutoFlush(AutoFlushEvent event)
at NHibernate.Impl.SessionImpl.AutoFlushIfRequired(ISet`1 querySpaces)
at NHibernate.Impl.SessionImpl.List(IQueryExpression queryExpression, QueryParameters queryParameters, IList results, Object filterConnection)
at NHibernate.Impl.SessionImpl.List(IQueryExpression queryExpression, QueryParameters queryParameters, IList results)
at NHibernate.Impl.AbstractSessionImpl.List(IQueryExpression queryExpression, QueryParameters parameters)
at NHibernate.Impl.AbstractQueryImpl2.List()
at NHibernate.Linq.DefaultQueryProvider.ExecuteQuery(NhLinqExpression nhLinqExpression, IQuery query, NhLinqExpression nhQuery)
at NHibernate.Linq.DefaultQueryProvider.Execute(Expression expression)
at NHibernate.Linq.DefaultQueryProvider.Execute[TResult](Expression expression)
at System.Linq.Queryable.Single[TSource](IQueryable`1 source, Expression`1 predicate)
at TestNhBug.Program.GetOrCreateEntry(ISession session, FileEntry parent, String name, Byte[] data) in c:\users\markjunker\source\repos\TestNhBug\TestNhBug\Program.cs:line 99
at TestNhBug.Program.Main(String[] args) in c:\users\markjunker\source\repos\TestNhBug\TestNhBug\Program.cs:line 36
This are my mappings:
<?xml version="1.0" encoding="utf-8"?>
<hibernate-mapping
assembly="TestNhBug"
namespace="TestNhBug"
xmlns="urn:nhibernate-mapping-2.2">
<class name="FileEntry" table="filesystementries">
<id name="Id" column="id" generator="assigned" />
<property name="ParentId" column="parent_id" />
<property name="Name" column="name" length="50" not-null="true" />
<one-to-one name="Data" lazy="no-proxy" cascade="all-delete-orphan" />
</class>
<class name="FileData" table="filesystementrydata">
<id name="Id" column="id">
<generator class="foreign">
<param name="property">Entry</param>
</generator>
</id>
<property name="Data" column="data" not-null="true" type="BinaryBlob" lazy="true" />
<one-to-one name="Entry" lazy="no-proxy" constrained="true" foreign-key="fk_data_entry" />
</class>
</hibernate-mapping>
This is my test application:
using System;
using System.Linq;
using System.Text;
using NHibernate;
namespace TestNhBug
{
class Program
{
private static readonly Guid RootGuid = Guid.Parse("00000000-0000-0000-0000-000000000001");
static void Main(string[] args)
{
var connectionString = @"Data Source=(LocalDb)\MSSQLLocalDB;Integrated Security=SSPI";
var cfg = new NHibernate.Cfg.Configuration();
cfg.SetProperty(NHibernate.Cfg.Environment.Dialect, "NHibernate.Dialect.MsSql2012Dialect");
cfg.SetProperty(NHibernate.Cfg.Environment.ConnectionString, connectionString);
cfg.AddAssembly(typeof(FileData).Assembly);
var updater = new NHibernate.Tool.hbm2ddl.SchemaUpdate(cfg);
updater.Execute(true, true);
try
{
using (var sf = cfg.BuildSessionFactory())
{
using (var session = sf.OpenSession())
{
using (var trans = session.BeginTransaction())
{
var rootEntry = GetOrCreateRootEntry(session);
GetOrCreateEntry(session, rootEntry, "text1.txt",
Encoding.UTF8.GetBytes("text1"));
var subEntry = GetOrCreateEntry(session, rootEntry, "test1");
GetOrCreateEntry(session, subEntry, "text1.txt",
Encoding.UTF8.GetBytes("text1 below test1"));
trans.Commit();
}
}
}
using (var sf = cfg.BuildSessionFactory())
{
using (var session = sf.OpenSession())
{
using (var trans = session.BeginTransaction())
{
var entry = GetForPath(session, "test1", "text1.txt");
session.Delete(entry);
trans.Commit();
}
}
}
}
catch (Exception ex)
{
Console.Error.WriteLine(ex);
}
}
private static FileEntry GetForPath(ISession session, params string[] path)
{
var found = session.Load<FileEntry>(RootGuid);
foreach (var pathPart in path)
{
var next = session.Query<FileEntry>()
.Single(x => x.ParentId == found.Id && x.Name == pathPart);
found = next;
}
return found;
}
private static FileEntry GetOrCreateRootEntry(ISession session)
{
var entry = session.Get<FileEntry>(RootGuid);
if (entry != null)
return entry;
entry = new FileEntry()
{
Id = RootGuid,
Name = string.Empty,
};
session.Save(entry);
session.Flush();
return entry;
}
private static FileEntry GetOrCreateEntry(ISession session, FileEntry parent, string name, byte[] data = null)
{
var entry = session.Query<FileEntry>()
.SingleOrDefault(x => x.Name == name && x.ParentId == parent.Id);
if (entry != null)
return entry;
entry = new FileEntry()
{
Id = Guid.NewGuid(),
ParentId = parent.Id,
Name = name,
};
FileData fileData;
if (data != null)
{
fileData = new FileData
{
Entry = entry,
Data = data,
};
entry.Data = fileData;
}
else
{
fileData = null;
}
session.Save(entry);
if (fileData != null)
{
session.Save(fileData);
}
session.Flush();
return entry;
}
}
public class FileData
{
public virtual Guid Id { get; set; }
public virtual byte[] Data { get; set; }
public virtual FileEntry Entry { get; set; }
}
public class FileEntry
{
public virtual Guid Id { get; set; }
public virtual Guid? ParentId { get; set; }
public virtual string Name { get; set; }
public virtual FileData Data { get; set; }
}
}