How to handle JPA annotations for a pointer to a generic interface - orm

I have a generic class that is also a mapped super class that has a private field that holds a pointer to another object of the same type:
#MappedSuperclass
public abstract class MyClass<T extends MyIfc<T>>
implements MyIfc<T>
{
#OneToOne()
#JoinColumn(name = "previous", nullable = true)
private T previous;
...
}
My problem is that Eclipse is showing an error in the file at the OneToOne "Target Entity "T" for previous is not an Entity." All of the implementations of MyIfc are, in fact, Entities. I should also add that each concrete implementation that inherit from MyClass uses a different value for T (because T is itself) so I can't use the "targetEntity" attribute.
I guess if there is no answer then I'll have to move this JPA annotation to all the concrete subclasses of MyClass. It just seems like JPA/Hibernate should be smart enough to know it'll all work out at run-time. Makes me wonder if I should just ignore this error somehow.

My problem is that Eclipse is showing an error in the file at the OneToOne "Target Entity "T" for previous is not an Entity."
Yes, and even if T was extending an Entity, I am not aware of any JPA provider supporting this (that's just not part of the JPA spec anyway). For more feedback have a look at JPA Generic entities classes Mappedsuperclass are not possible! (very similar thread about EclipseLink):
No you will be unable to make the Entities generic. The provider will be unable to map the relationship to the specific type defined by the generic definition as this type is assigned when the Entity is created in code not where the Entity is defined. Remember when designating Generics the Collection (in this case) is limited only to those types. The Provider can not possibly be this restrictive on a per Entity instance basis. In some cases changing the type may result in entirely different tables being mapped for a single Entity instance and that is definitely not supported.

Since JDO supports persistence of interface fields (which is a similar concept to what you have here), and since DataNucleus JPA is built on top of the JDO capabilities, then it likely would allow you to persist such a field (I have an example using JDO that does something very similar, but without seeing the remains of your classes and persistence code its impossible to be definitive). Give it a try and see what happens.
Obviously that is beyond the JPA spec, hence if portability is a concern for you then have a think first

You can add a #OneToOne(targetEntity=SuperClassOfT.class) to your fields to make this work.
Check out How to implement polymorphic JPA entities with generic relations

Related

Jackon JSON: Polymorphic deseralization when subclasses are unknown

I'm trying to do some polymorphic deseralization of JSON using Jackson, however the list of subclasses is unknown at compile time, so I can't use a #JsonSubtype annotation on the base class.
Instead I want to use a TypeIdResolver class to perform the conversion to and from a property value.
The list of possible subclasses I might encounter will be dynamic, but they are all registered at run time with a registry. So I would appear to need my TypeIdResolver object to have a reference to that registry class. It has to operate in what is essentially a dependency injection environment (i.e I can't have a singleton class that the TypeIdResolver consults), so I think I need to inject the registry class into the TypeIdResolver. The kind of code I think I want write is:
ObjectMapper mapper = new ObjectMapper();
mapper.something(new MyTypeIdResolver(subclassRegistry));
mapper.readValue(...)
However, I can't find a way of doing the bit in the middle. The only methods I can find use java annotations to specify what the TypeIdResolver is going to be.
This question Is there a way to specify #JsonTypeIdResolver on mapper config instead of annotation? is the same, though the motivation is different, and the answer is to use an annotation mixin, which won't work here.
SimpleModule has method registerSubtypes(), with which you can register subtypes. If only passing Classes, simple class name is used as type id, but you can also pass NamedType to define type id to use for sub-class.
So, if you do know full set, just build SimpleModule, register that to mapper.
Otherwise if this does not work you may need to resort to just sharing data via static singleton instance (if applicable), or even ThreadLocal.
Note that in the end what I did was abandon Jackson and write my own much simpler framework based on javax.json that just did the kinds of serialisation I wanted in a much more straightforward fashion. I was only dealing with simple DTO (data transfer object) classes, so it was just much simpler to write my own simple framework.

NHibernate and making an abstract entity base class

I saw in some NHibernate examples that an abstract base entity class is used, which has overridden Equals , GetHashCode , to handle transient entities , proxy object (in lazy loading scenario .. I guess) .
Is it really necessary to implement such an abstract base entity class to derive all my entities ?
Not necessary at all. It just makes things easier because you can put things like the Id on it. As well common functionality like you previously mentioned like Equals/GetHashCode.
Yeah, the base class itself is not required,but overriding Equals and GetHashcode is something you'll want to do on all your entities, so the base class makes thAt a lot less repetetive
In my experience, having a base class that exposes an Id property is really useful to be able to create generic repository methods that take advantage of that, or for automatic mapping conventions.
Overriding Equals, however, is another story.
Doing so forces loading of uninitialized proxies when you compare them (for example, by calling Distinct on a sequence). For that reason, it's better done only for class hierarchies of seldom-changing entities that are likely to be cached.
Overridding Equals is definetely required if you want to do lazy loading.
This is because NHibernate relies on the Equals method to determine equality. The default is reference equality.
When NHibernate implements lazy loading, it uses proxy objects, which are subclasses of the real entity class, with every member overridden to enable lazy loading.
Hence for your application to recognise that a proxy object is the same as the object it is meant to be the real instance - it shouldn't be aware of the proxy object at all.
So you must override the Equals operator to intelligently recognise equality (after checking reference equality ... etc) that objects are equal if their IDs are equal.

NHibernate: completely overriding base domain entity

I have a situation where I have a Common.Domain.Person and Specific.Domain.Person.
First one should be provided as a part of a common package.
Second one appears when common package has to be customized to fit the needs of specific project.
In the object model, it can be easily implemented with inheritance.
In the NH mapping, however, I have encountered a small problem.
I can create an NHibernate <subclass> mapping, but that would require me to use an discriminator. However, I know that if specific person class was inherited, then common class instances will never be used within this specific project.
What is the best way to implement this without adding discriminator column to the base class (since there are no different cases to discriminate)?
this is what i wanted and nhibernate supports it using xml entities. Unfortunately this feature has been borked since (at least) NH v2++.
see also Using Doctype in Nhibernate
A work-around could be to inject these properies programmaticaly when you create the SessionFactory (Dynamic Mapping)
see also http://ayende.com/Blog/archive/2008/05/01/Dynamic-Mapping-with-NHibernate.aspx
Just map the Specific.Domain.Person and leave Common.Domain.Person unmapped.
If you are not saving instances of it, NHibernate does not need to know about it.

How do you map an entity -> interface relationship using Fluent NHibernate?

given the following class definition:
public class Order {
public IProduct Product {get;set;}
}
I have this (fluent) mapping
References(x=>x.Product, "ProductId");
And get this exception: An association from the table Orders refers to an unmapped class, which makes sense because it doesn't know what implementation I will pass to it.
I understand why I have to define the type in the mapping (IProduct could be anything) but I'm not sure how to do it.
Thanks,
Kyle
I think what you're looking for is .References<Product>(x=>x.Product, "ProductId");
Incidentally the same is true for .HasMany<>
This seems to do the same as <... class="Product" /> in xml
I wouldn't recommend mapping to the interface as it breaks the whole point of using one - you run into problems as soon as it starts implementing IStorable and NH can't cope with the multiple inheritance.
Try mapping the interface IProduct instead of the concrete class Product. (Note, I'm not talking about mapping the Product field of class Order.)
You could map the interface->implementation relationship as an inheritance relationship, using an appropriate inheritance model.
That would mean mapping IProduct and then creating a subclass map of Product in the IProduct mapping, for example using table-per-hierarchy.
That would also let you map additional data in the product class that is not part of the IProduct interface, and also let you map additional IProduct implementations in the same way if you wish to.
I've been working on improving the support for proxy interfaces in Fluent. There were a couple of useful patches attached to issues 256 and 257, but they really needed everything specified manually. I've taken these a step further and added support for setting proxies and changing the types of references from the inferred (which would be the proxy) to the underlying mapped class, and added a new convention (ProxyConvention) to set it all up automatically - just instantiate it with a function to derive the proxy interface from a mapped class, and it should take care of the rest.
The one loophole at the moment is that it can't pick up any definitions specified explicitly in .hbm.xml files.
The patch is attached to issue 256

Is it possible to use NHibernate without altering a DDD model that is part of a framework

I dig a lot of things about the DDD approach (Ubiquitous language, Aggregates, Repositories, etc.) and I think that, contrary to what I read a lot, entities should have behavior rather then being agnostic. All examples I see tend to present entities with virtual automatic properties and an empty constructor (protected or worst, public) and that's it. I consider this kind of objects more like DTOs then entities.
I'm in the process of creating a framework with its specific API and I don't want to be tied to an ORM. So I built the domain first (without thinking of persistence) and now I would like to use NHibernate as persistence tool so I added a new project to my current solution to help ensure that my model isn't altered to support NHibernate. This project should be an implementation of the abstract repositories that live inside my domain. And now the difficulties arise.
Since it is my first time with NHibernate (I'm also trying Fluent Nhibernate but it seems even more restricting) I would like to know :
Is it possible to use NHibernate without altering a DDD model that is part of a framework
The things (constraints) that are necessary for NHibernate to work as expected and efficiently (virtual properties, empty constructors, etc.) I think this list would be helpful to a lot of people who are starting to learn NHibernate.
Please keep in mind that I'm building a framework so the Open/Closed Principle is very important for me.
P.S.: Sorry if my english is not good, I'm from Montreal and I speak french.
Edit 1: Here is one problem I have with NHibernate now - How to map Type with Nhibernate (and Fluent NHibernate)
For NHibernate:
All mapped classes require a default (no-arguments) constructor. The default constructor does not have to be public (it can be private so that it is not a part of the API), but it must exist. This is because NHibernate must be able to create an instance of the mapped class without passing any arguments. (There are workarounds, but don't do that.)
All mapped properties for which lazy-loading will be required must be marked virtual. This includes all reference properties and all collection properties. This is because NHibernate must be able to generate a proxy class deriving the mapped class and overriding the mapped property.
All mapped collection properties should use an interface as the property type. For example, use IList<T> rather than List<T>. This is because the collections types in the .NET Framework tend to be sealed, and NHibernate must be able to replace a default instance of the collection type with its own instance of the collection type, and NHibernate has its own internal implementations of the collection types.
For NHibernate, prefer Iesi.Collections.Generic.ISet<T> to System.Collections.Generic.IList<T>, unless you are sure that what you want is actually a list rather than a set. This requires being conversant in the theoretical definitions of list and set and in what your domain model requires. Use a list when you know that the elements must be in some specific order.
Also note that it's typically not easy to swap object-relational mapping frameworks, and in many cases it is impossible, when you have anything beyond a trivial domain model.
The short answer to your question is that it is not possible, but if don't need lazy loading the required alterations are trivial.
No matter what, you will have add default constructors to classes that do not already have them. If you are willing to forgo lazy-loading, those default constructors can be private, and you don't have to make any other changes to your domain model to use NHibernate.
That's awfully close to persistence ignorance.
Having said that, if you want lazy-loading, you'll need to make several changes (outlined in other answers to this question) so that NHibernate can create proxies of your aggregated entities. I'm personally still trying to decide whether lazy-loading is an enabling technology for DDD or if it's a premature optimization that requires too many intrusive changes to my POCOs. I'm leaning toward the former, though I really wish NHibernate could be configured to use a specific constructors.
You might also take a look at Davy Brion's blog (I particularly liked Implementing A Value Object With NHibernate), which is really illuminating if you're interested in domain-driven-design and avoiding anemic domain models.
In my experience, the only thing that NHibernate requires of a domain is virtual properties and methods and a default no-argument constructor, which as Jeff mentioned, can be marked private or protected if need be. That's it. NHibernate is my OR/M of choice, and I find the entire NHibernate stack (NHibernate, NHibernate Validator, Fluent NHibernate, LINQ to NHibernate) to be the most compelling framework for persisting POCO domains.
A few things you can do with NHibernate:
Decorate your domain model with NHV attributes. These constaints allow you to do three things: validate your objects, ensure that invalid entities are not persisted via NHibernate, and help autogenerate your schema when using using NHibernate's SchemaExport or SchemaUpdate tools.
Map your domain model to your persistent storage using Fluent NHibernate. The main advantage, for me, in using FNH is the ability to auto map your entities based on conventions that you set. Additonally, you can override these automappings where necessary, manually write class maps to take full control of the mappings, and use the xml hbm files if you need to.
Once you buy into using NH, you can easily use the SchemaExport or SchemaUpdate tools to create and execute DDL against your database, allowing you to automatically migrate domain changes to your database when initilizing the NH session factory. This allows you to forget about the database, for all intents and purposes, and concentrate instead on your domain. Note, this may not be useful or ideal in many circumstances, but for quick, local development of domain-centric apps, I find it convenient.
Additionally, I like using generic repositories to handle CRUD scenarios. For example, I usually have an IRepository that defines methods for getting all entites as an IQueryable, a single entity by id, for saving an entity, and for deleting an entity. For anything else, NH offers a rich set of querying mechanisms -- you can use LINQ to NHibernate, HQL, Criteria queries, and straight SQL if need be.
Th only compromise you have to make is using NHV attributes in your domain. This is not a deal breaker for me, since NHV is a stand-alone framework which adds additional capabilities if you choose to use NHibernate.
I have built a few apps using NH, and each has a persistence ignorant domain with all persistence concerns separated into its own assembly. That means one assembly for your domain, and another for your fluent mappings, session management, and validation integration. It's very nice and clean and does the job well.
By the way: your English is pretty darn good, I wish my French was up to par ;-).
Just to put my two bits in, I struggled with the same thing once but I overcame this by:
Adding protected default constructor to every entity.
Making Id virtual
Let's take for example upvote and downvote for Vote entity on my experiment website:
http://chucknorrisfacts.co.uk/ (NHibernate + MySQL with Mono)
public class Vote : Entity
{
private User _user;
private Fact _fact;
// true: upvote, false: downvote
private bool _isupvoted;
// for nHibernate
protected Vote() { }
public Vote(User user, Fact fact, bool is_upvoted)
{
Validator.NotNull(user, "user is required.");
Validator.NotNull(fact, "fact is required.");
_fact= fact;
_user = user;
_isupvoted = is_upvoted;
}
public User User
{
get { return _user; }
}
public Fact Fact
{
get { return _fact; }
}
public bool Isupvoted
{
get { return _isupvoted; }
}
}
This class inherits from Entity where we stick all the minimum necessary for Nhibernate.
public abstract class Entity
{
protected int _id;
public virtual int Id { get {return _id;} }
}
and Fluent mapping where you Reveal the private property.
public class VoteMap : ClassMap<Vote>
{
public VoteMap()
{
DynamicUpdate();
Table("vote");
Id(x => x.Id).Column("id");
Map(Reveal.Member<Vote>("_isupvoted")).Column("vote_up_down");
References(x => x.Fact).Column("fact_id").Not.Nullable();
References(x => x.User).Column("user_id").Not.Nullable();
}
}
You could probably place protected default constructor in Entity class and configure nHibernate to use it instead but I didn't look into it yet.