Named query on abstract entity - entity

I have 3 entities in hierarchy:
Request.java
#Entity
#Table(name="Request")
#Inheritance(strategy=InheritanceType.JOINED)
#DiscriminatorColumn(name="REQUEST_TYPE", discriminatorType=DiscriminatorType.INTEGER)
#NamedQuery(name="getRequestsById", query="select r from Request r where r.id=:id and r.status=100")
public abstract class Request implemenst Serializable {
...
}
MedicineRequest.java
#Entity
#Table(name="MED_REQUEST")
public abstract class MedicineRequest extends Request {
...
}
ExtendedMedicineRequest.java
#Entity
#Table(name="EXT_MED_REQUEST")
#DiscriminatorValue("1")
public class ExtendedMedicineRequest extends MedicineRequest {
...
}
Where I'm trying to run the above query, getRequestsById, I'm getting the following error message:
Cannot instantiate abstract class of type "Request" with object id "Request-RequestPK#c49aa166"; this may indicate that the inheritance discriminator for the class is not configured correctly.
All the entities are defined properly in persistance.xml, name of the discriminator column is correct too. What can be the matter??

No, it's ok to the entity to be abstract. But I found the reason. The query is generic, so it requests instantiation of sons of this entity. One of sons has relationship to other entity that uses enum from the utility jar. But...jpa project has this jar on the build path, wheh the EAR project doesn't include this jar in module list, so finally, the jar wasn't on the classpath in runtime. The error message was commonly irrelevant in this case.

The reason is "Cannot instantiate abstract class of type", your Request class is abstract. Why? It's an entity then it SHOULDN'T be abstract.

Related

Can razorpages have a common base class beside pagemodel?

Can I create a base class to use for several razorpages, as long as the base class inherits from PageModel? I have not seen any examples using this approach, but it would seem like a good way to setup dependencies that need to be injected. Rather than inject on each page model constructor, do it once in the base.
You can't inherit from multiple classes, c# allows inheriting from only one base class. But you still able to implement multiple interfaces beside the base PageModel.
As a workaround, your base class can inherit from another base class that has PageModel as base class and so on... but try not to avoid the kiss principle (see Programming principles)
public class MyBasePageModel : PageModel
{
// custom implementations...
}
Then apply to IndexModel:
public class IndexModel : MyBasePageModel
{
// ...
}

ninject ioc with inherited base generic repository

I have a generic repository, abstract and concrete as below
public interface IGenericRepository<T> where T : class
public class GenericRepository<T> : IGenericRepository<T> where T : class
I then have an repository that inherits from this, again abstract and concrete
public interface ISkyDiveCentreRepository : IGenericRepository<DiveCentre>
public class SkyDiveCentreRepository : GenericRepository<DiveCentre>
In my ninject config I then have
kernel.Bind(typeof(IGenericRepository<>)).To(typeof(GenericRepository<>));
kernel.Bind<ISkyDiveCentreRepository>().To<SkyDiveCentreRepository>();
This is the first time I've tried to do this but am getting the error:
Error 2 The type 'UKSkyDiveCentres.DAL.imp.SkyDiveCentreRepository' cannot be used as type parameter 'TImplementation' in the generic type or method 'Ninject.Syntax.IBindingToSyntax<T1>.To<TImplementation>()'. There is no implicit reference conversion from 'SkyDiveCentres.DAL.imp.SkyDiveCentreRepository' to 'SkyDiveCentres.DAL.ISkyDiveCentreRepository'. C:SOMEPATH\UKSkyDiveCentres\App_Start\NinjectWebCommon.cs 56 13 SkyDiveCentres
Your SkyDiveCentreRepository inherits from GenericRepository<DiveCentre> and doesn't implement the ISkyDiveCentreRepository interface.
Simply explicitly implement it:
public class SkyDiveCentreRepository :
GenericRepository<DiveCentre>, ISkyDiveCentreRepository
// ^^^^^^^^^^^^^^^^^^^^^^^^ this
Without it.. you can't do simple things like this:
ISkyDiveCentreRepository repo = new SkyDiveCentreRepository();
If you can't do it.. Ninject can't either.

Under what scenarios a developer should inherit constructors and destructors of a parent class into child class?

As all private and public attributes and methods are inherited into a child class from its parent class then why would constructors and destructors be inherited into a child class?
Is there a real life scnario?
In most programming languages constructors and descructors are not inherited automatically. Usually base class can provide one set of constructors and child class can provide another set of constructors.
I think that in most cases abstract derived class should provide the same set of constructor as base class do (i.e. "inherit" constructors from the base class), but concrete derived class can resolve some of base class's constructor arguments and provide more usable set of constructors:
Consider following case. Let suppose we have a base class called BaseWCFProxy that requires string as endpoint name:
abstract class BaseWCFProxy
{
public BaseWCFProxy(string endpointName)
{}
}
class ConcreteProxy : BaseWCFProxy
{
public ConcreteProxy() : base("ConcreteProxyEndPoint") {}
}
But you decide to add additional abstract class between BaseProxy and ConcreteProxy than you should provide the same set of constructors as base class:
class DualChannelBaseProxy : BaseWCFProxy
{
public DualChannelBaseProxy(string enpointName) : base(endpointName) {}
}
So the rule of thumb is: if you write a abstract child you should consider to "inherit" all base classes constructors. If you write a concrete child you can provide separate set of constructors that would be appropriate for your clients.
P.S. We don't have the same issue with destructors because there is no such notion like destructors overloading. And they're inherited by default: i.e. descendant can provide some additional logic but it definitely should call base version.

Mapping inheritance in NHibernate 3.3

I have the inheritance described below :
public abstract class BaseEntity<TId> {....}
public abstract class ModelEntity : BaseEntity<Int32>{....}
public abstract class AuditableEntity : ModelEntity,IAuditable{....}
public class ApplicationUser : AuditableEntity{....}
public class SuperUser : ApplicationUser
I am using NHibernate 3.3 and I want to Create the mappings for that inheritance
public abstract class ModelEntityMap<TEntity> : ClassMapping<TEntity>
where TEntity : ModelEntity
{...}
public class AuditableEntityMap<TEntity> : ModelEntityMap<TEntity> where TEntity : AuditableEntity
{ ...}
public class ApplicationUserMap : AuditableEntityMap<ApplicationUser>
{...}
public class SuperUserMap : JoinedSubclassMapping<SuperUser>{...}
When the application starts and trys to set up the database it raises the following Exception :
Ambiguous mapping for SuperUser More than one root entities was found BaseEntity / ApplicationUser
Possible solutions
-Merge the mapping of root Entity in the one is representing the real root in the hierarchy
-Inject a IModelInspector with a logic to discover the real root-entity.
I was using Fluent nhibernate with the same inheritance and worked fine with SuperUserMap defined as
public class SuperUserMap : SubClassMap {...}
I am new to Nhibernate mapping by code and quite confused !!!
I believe there are two ways to solve this problem:
a) Using the concept of discriminator that identifies the type of the class stored and thereby the right object is retrieved from the database, in this case your class is mapped to a table that has all the columns plus the discriminator columns. Not sure how this works with multi-level inheritance but this is something that you can google.
b) take a look at this post on how he deals with inheritance: http://fabiomaulo.blogspot.co.nz/2011/04/nhibernate-32-mapping-by-code_13.html you might get some idea to solve your issue.
You can influence the decision whether an entity is a root entity by overriding the IsRootEntity logic of the model mapper that you use to create mappings.
Here's an example that defines the default NHibernate mapping-by-code behaviour:
var modelMapper = new ConventionModelMapper();
modelMapper.IsRootEntity((type, declared) =>
{
if (declared) return true; // Type has already been declared as root entity
return type.IsClass
&& typeof(object) == type.BaseType
&& modelMapper.ModelInspector.IsEntity(type);
});
You will have to tweak this decision logic to exclude the BaseEntity class as possible root entity.
I had this error with NHibernate 4.1.1 (May 2017), so I'm answering with how I solved it for future reference
In my case, I copied an existing mapping of an inheriting class, and forgot to change the parent mapping class to ClassMapping and encountered the same error
In other words, in your mapping class, check the parent class, make sure it is ClassMapping or JoinedSubclassMapping if it's a child class

NHibernate narrowing proxy warning

We are building an ASP.NET MVC application utilizing NH for data access. Using NH Profiler I see a lot of warnings like "WARN: Narrowing proxy to Domain.CaseTask - this operation breaks ==". I get these very often when executing queries for classes which are mapped in a table per subclass, for example, using the NH Linq provider:
Query<ICaseTask>().Where(c => c.Assignee == Of || c.Operator == Of)
where the class CaseTask inherits from Task, triggers the warning.
Information about the warning in the internet is scarce and mostly hints that this is something to be ignored... What does this warning warn about exactly? Should this be something I should seek to correct?
The reality is more complicated. When you load entity using either session.Load or you access a property that is lazy loaded NHibernate returns a proxy object. That proxy object will by hydrated (data will be loaded from DB) when you access any of its properties for the first time. To achieve this NHibernate generates proxy class that extends entity class and overrides all property getters and setters. This works perfectly when inheritance is not used since you will have no way to differentiate between proxy and entity class (proxy base class), e.g. simple test proxy is MyEntity will always work.
Now imagine that we have a Person entity:
class Person {
// lazy-loaded
public Animal Pet { get; set; }
}
And we also have Animal class hierarchy:
public abstract class Animal { ... }
public class Cat { ... }
public class Dog { ... }
Now assume that Pet property is lazy loaded, when you ask NHibernate for person pet you will get a proxy object:
var pet = somePerson.Pet; // pet will be a proxy
But since Pet is lazy loaded property NH will not know if it will be instance of a Cat or a Dog, so it will do its best and will create a proxy that extends Animal. The proxy will pass test for pet is Animal but will fail tests for either pet is Cat or pet is Dog.
Now assume that you will access some property of pet object, forcing NH to load data from DB. Now NH will know that your pet is e.g. a Cat but proxy is already generated and cannot be changed.
This will force NHibernate to issue a warning that original proxy for pet that extends type Animal will be narrowed to type Cat. This means that from now on proxy object for animal with pet.Id that you create using session.Load<Animal>(pet.Id) will extend Cat from now. This also means that since Cat is now stored as a part of session, if we load a second person that shares cat with the first, NH will use already available Cat proxy instance to populate lazy-loaded property.
One of the consequences will be that object reference to pet will be different that reference obtained by session.Load<Animal>(pet.Id) (in object.ReferencesEqual sense).
// example - say parent and child share *the same* pet
var pet = child.Pet; // NH will return proxy that extends Animal
pet.DoStuff(); // NH loads data from DB
var parent = child.Parent; // lazy-loaded property
var pet2 = parent.Pet; // NH will return proxy that extends Cat
Assert.NotSame(pet, pet2);
Now when this may cause harm to you:
When you put your entities into Sets or Dictionaryies in your code or if you use any other structure that requires Equals/GetHashCode pair to work. This can be easily fixed by providing custom Equals/GetHashCode implementation (see: http://www.onjava.com/pub/a/onjava/2006/09/13/dont-let-hibernate-steal-your-identity.html?page=1)
When you try to cast your proxy object to target type e.g. (Cat)pet, but again there are know solutions (e.g. Getting proxies of the correct type in NHibernate)
So the moral is to avoid as much as possible inheritance in your domain model.
This warning is about classes having properties or fields that are a subclass. IE:
public class Animal
{
public int Id {get;set;}
}
public class Cat : Animal
{
public int Weight {get;set;}
}
public class Person
{
public Cat Pet {get;set;}
}
NHibernate gets upset when it loads the person entity because it doesn't want to cast for you because behavior becomes unpredictable. Unless you tell NHibernate how to deal with Equals (among other logic) it won't know how to do that comparison on its own.
The basic idea to correct this is to let NHibernate put the base class object into the graph and then you deal with the casting (note that this setup would use some slightly different mappings - ive done this to simplify the code but it can obviously be done by keeping the properties as full getters/setters):
public class Animal
{
public int Id {get;set;}
}
public class Cat : Animal
{
public int Weight {get;set;}
}
public class Person
{
private Animal _pet;
public Cat Pet {
get{return _pet as Cat;}
}
}