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.
Related
I've been working with NHibernate for quite a while and have come to realize that my architecture might be a bit...dated. This is for an NHibernate library that is living behind several apps that are related to each other.
First off, I have a DomainEntity base class with an ID and an EntityID (which is a guid that I use when I expose an item to the web or through an API, instead of the internal integer id - I think I had a reason for it at one point, but I'm not sure it's really valid now). I have a Repository base class where T inherits from DomainEntity that provides a set of generalized search methods. The inheritors of DomainEntity may also implement several interfaces that track things like created date, created by, etc., that are largely a log for the most recent changes to the object. I'm not fond of using a repository pattern for this, but it wraps the logic of setting those values when an object is saved (provided that object is saved through the repository and not saved as part of saving something else).
I would like to rid myself of the repositories. They don't make me happy and really seem like clutter these days, especially now that I'm not querying with hql and now that I can use extension methods on the Session object. But how do I hook up this sort of functionality cleanly? Let's assume for the purposes of discussion that I have something like structuremap set up and capable of returning an object that exposes context information (current user and the like), what would be a good flexible way of providing this functionality outside of the repository structure? Bonus points if this can be hooked up along with a convention-based mapping setup (I'm looking into replacing the XML files as well).
If you dislike the fact that repositories can become bloated over time then you may want to use something like Query Objects.
The basic idea is that you break down a single query into an individual object that you can then apply it to the database.
Some example implementation links here.
And here goes yet another question on NHibernate.
This one most likely doesn't have a desired answer, but still - let's give it a try.
I'm currently putting all the efforts into mapping a domain model onto the database using NHibernate. This domain model comes from a framework which is heavily obfuscated. (Not that I have worked a lot with obfuscated code before, but this one in most of the places can be translated neither by Reflector, nor by Resharper.)
Everything went more or less fine until I faced an entity with a required many-to-one relationship represented by a property with no setter with obfuscated backed field.
Is it possible to reference this obfuscated field somehow? A very special IPropertyAccessor?
If not, how can I load a fully constructed entity? The only option to inject a related object is by using a constructor that accepts it. But at the time of instantiating of an entity being loaded, neither IInstantiator nor IInterceptor has any data of it apart from the key. Any other extension points that suit my need?
To allow NHibernate to access your field instead of property you can use this in your mappings:
access="field"
I'm working on a project to replace ADO.NET data access logic using NHibernate where we're not able to map the entire domain model at once. This means we'll have domain classes with property mappings to other domain classes that aren't yet mapped with NHibernate.
Consider a Person class with an Address property (Address being a domain object without an NH mapping and Person being the class I'm mapping). How can I include Address in the Person mapping without creating an entire mapping for Address?
Is it possible to call legacy (ADO.NET) data access logic from a custom PropertyAccessor? If so, is it reasonable?
*I asked this within another question here but didn't get a response. I'm hoping to get one in a more concise question.
In your example even if you didn't create a mapping file for Address, it would potentially be as much work as creating the mapping file itself. There are a some other options you may consider during your transition, like have a custom DAL with a method 'GetPerson', for example, that would NH load person and ADO load address. Not pretty or efficient, but encapsulates the work, so the interface doesn't change when you want to map Address. That being said there are some options for creating custom data tranforms using NHibernate.Transform.AliasToBeanResultTransformer. But really in the end you have to find a good way to chunk out pieces of your domain model. Using a DAL is both good practice and can be a decent bridge out of ADO and into the NH madness.
Is this possible in fluent nhibernate having multiple mappings for one table? Lets suppose i have a Users table.
Once i want it to be apped exactly like in file UserMap1.cs, and some times I would rather prefer mapping from UserMap2.cs.
I don't need to switch configurations while app is running. I just have to choose a proper one at the beginning.
Thanks in advance:-)
This might be a hack, but you could possibly put your two mappings into separate namespaces. Then you could add mappings from either one namespace or the other depending on your needs.
You're using Fluent NHibernate, so you're likely using the Mappings.FluentMappings object. I normally invoke AddAssemblyFrom (providing a type in the assembly containing mappings). You may need to invoke the Add or Add(Type type) method to add them invididually. My thought is to use MEF to attribute your ClassMap subclasses and add metadata in select cases to determine which ones to inject.
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