开发者

ERROR: Loading object was of wrong class

I have an MVC/Nhibernate app that is giving me the below.

[WrongClassException: Object with id: f7eab616-76b2-4602-8643-b4466e91a33f was not of the specified subclass: AgileThought.ERP.Domain.CRM.Client (loading object was of wrong class [AgileThought.ERP.Domain.HR.SalesRepresentative])] NHibernate.Loader.Loader.InstanceAlreadyLoaded(IDataReader rs, Int32 i, IEntityPersister persister, EntityKey key, Object obj, LockMode lockMode, ISessionImplementor session) +229

I believe from the stack trace that the line NHibernate.Loader.Loader.InstanceAlreadyLoaded says the object is already loaded.

The problem is that the object may be of a few types which have the same GUID. IE

a Client Inherits from a Person

a Employee Inherits from a Person

a Sales Rep Inherits from Employee

In my dev environment, my user account has all three entity types.

The problem is that now when I do a search on a Client, it sees the GUID from a Sales Rep and assumes that I want my Sales Rep object. The next line of my code fails as it is expecting a Client list, but one object is a Sales Rep.

I have seen several similar issue in searching but they all seem to revolve around using a discriminator. I have a seperate table for each of these sub classes, just listing the GUID and any extra properties. I have also seen this error reported with hibernate (java) as a code error, but the article said it was corrected in Nhibernate Port wtih a broken link to the issue.

The Nhibernate API query specifies my object type it should be getting, so I am not sure what else I can do. Is there a way to force a fresh query?

The situation is unlikely to occur in real life, but I am concerned that I my login cant be both a client and a sales rep under the current situation, I have no doubt this will cause greater issue elswhere in the application where some other person types will be used. (Each type has a few seperate properties, I dont want to use a disctiminator or user Roles to specifiy there person type.)

Any advise would be much appreciated.

Please find code below.

Search Method:

 public IEnumerable<Client> NewContacts(Guid userGUID)
    { 
         SalesRepresentative rep = new SalesRepresentativeRepository().GetById(userGUID);
         List<Client> result = new List<Client>();
         using (ISession session = NHibernateHelper.OpenSession())
         {
             foreach (var i in rep.Projects)
             {
                 ICriteria criteriaPerson = session.CreateCriteria(typeof(Client));
                 criteriaPerson.CreateAlias("ProjectsOfInterest","p");
                 criteriaPerson.Add(Expression.Eq("p.EntityGUID", i.EntityGUID));
                 //Distinct
                 criteriaPerson.SetResultTransformer(new NHibernate.Transform.DistinctRootEntityResultTransformer());

                 result.AddRange(criteriaPerson.List<Client>());
             }
             return result.Distinct();
         }
    }

The object is loaded already loaded as a Sales Rep on the line:

SalesRepresentative rep = new SalesRepresentativeRepository().GetById(userGUID);

The issue is on the line:

result.AddRange(criteriaPerson.List<Client>());

because one of my clients is me, the Sales Rep.

Originally this code didn't have a loop around the project, but an inner join via alias's. This was just one attempt to find an answer by taking it out of the query, 开发者_如何转开发but it had the same result.

                 ICriteria criteriaPerson = session.CreateCriteria(typeof(Client));
                 criteriaPerson.CreateAlias("ProjectsOfInterest", "p");
                 criteriaPerson.CreateAlias("ProjectsOfInterest.SalesRepresentatives", "rep");
                 criteriaPerson.Add(Expression.Eq("rep.EntityGUID", userGUID));


I fell in this same error today (for the second time actually) and I finally realized what's the issue here.

I don't knwo abount others ORM but using nHibernate you can't share an Id over two different classes (subclasses). That's not the way inheritance is supposed to be in nHibernate. Table-per-class hierarchy is meant to have separate tables to specify a parent table (in your issue you are trying the opposite).

All this actually make sense since to access Client or Employee you actually refer to the Person Id (at first I didn't paid attention to this but now is totally clear).

The solution is to refactor the domain model and change the relationship between you classes from as "is-a" to a "has-a" relationship and expose common properties (if needed) via an interface.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜