Can I see nhibernate automapper mappings - nhibernate

Automapping in Nhibernate has been this wonderful magical thing, but now something strange is happening and I want to peel back this magical layer and see the actual mappings that are getting generated.
Is there a way to see the mappings generated by automapper and my overrides so I can see if it's doing what I think it's doing?

If you are using Fluent then you should be able to write the persistence model to the disk:
// In your fluent config code
// assuming config is of type FluentNHibernate.Cfg.FluentConfiguration
var model = new FluentNHibernate.PersistenceModel();
config.Mappings(m => m.UsePersistenceModel(model));
model.WriteMappingsTo(#"C:\some_folder_name_for_hbm_files_to_go_into");

Related

NH 3.2 Fluent Mapping Lazy Loading

I used NH 3.2 mapping by code and I tryied Nhibernate Mapping Generator http://nmg.codeplex.com/ which looked a great tool.
I found a big difference between my code and theirs. On each class they have a call to the function LazyLoad(). (Although I thinked that it was the default behaviour)
Now I fear that my application doesn't use lazy loading, does someone know the default behaviour of nh 3.2 with mapping by code ? (when we don't call the LazyLoad method)
Regards
Depends on the default-lazy attribute of the hibernate-mapping tag which can be changed in Fluent NHibernate by adding the DefaultLazy.Always() or DefaultLazy.Never() convention.
If no default-lazy attribute is defined (no convention added in Fluent NHibernate), lazy loading is enabled.

Can I give an nhibernate session factory a list of mappings to load?

Right now, the session factory just finds all .hbm.xml files embedded in the current assembly it seems. I now have a situation where I only want the session factory to load the list of mappings that I specify. How can I do this?
Thanks,
Isaac
You can use the Configuration.AddResources(IEnumerable<string> paths, Assembly assembly) and specify a desired list of mappings, do your own filtering if you insist having the mappings embedded in the same assembly. Otherwise I would recommend Sergio's answer.
You can use a static method on Configuration class to return a list of available mappings in an assembly, then you can remove the ones you don't want:
var mappings = Configuration.GetAllHbmXmlResourceNames(assembly);
// TODO: filter mappings
cfg.AddResources(mappingsFiltered, assembly);
Well, in the configuration of NHibernate, you specify the assembly where you have embedded your mappings right? What I would suggest is change that configuration dynamically based on your needs.
Another way to do it at run-time would be using the NHibernate.cfg.Configuration.CreateMappings method to create the mappings dynamically. This would require you to create the mappings either on the fly (you can read from a DB or files or something). I personally haven't done this way but I think you could give it a try to solve your needs.
Hope this helps.

JPA <pre-persist> <pre-update> are being ignored but the #PrePersist and #PreUpdate work fine

I ran into strange problem. I have the whole domain model defined in the orm.xml file. All my entities in my project are just simple POJOs (no jpa annotations at all). I want to save the last update and the insert timestamps of my entities and I've decided to use the "pre persist" and "pre update" like most of us. So I've defined a base entity class and let all my entities to extend it.
Strange is that the "pre persist" (and all others events) are being called only when I define them using annotations. When I define them in the orm.xml file instead - nothing happens, they are just ignored.
This works for me:
public abstract class BaseEntity {
private Timestamp insertTimestamp;
private Timestamp lastUpdateTimestamp;
#PrePersist
public void onPersist() {
...
}
#PreUpdate
public void onUpdate() {
...
}
}
But after removing annotations and switching to the xml nothing works anymore:
<mapped-superclass class="com.my.model.BaseEntity">
<pre-persist method-name="onPersist"/>
<pre-update method-name="onUpdate"/>
<post-load method-name="postLoad"/>
</mapped-superclass>
According to the JPA specification the above declarations in xml seem to be correct.
I have no idea where to dig for the problem.
I'm using EclipseLink 2.2.0 with H2 in the SE environment.
UPDATE:
Thanks for your answer. There are no errors in log/console to see. Events just seem being ignored.
As you thought is might be a bug because moving the methods and XML declarations from the superclass to the subclass solves the problem. It is not a desired solution for me as I want to have a global solution for all entities but moved me a bit forward.
I've sent the bug report to the EclipseLink guys :)
As you suggested I've tried with entity listener and it works for me. so I will stick to this solution. It even looks better then the solution with base entity class ;)
Thanks !
Your XML looks correct. Do any errors occur in the logs?
It could be a bug with MappedSuperClass and entity events.
Can you try setting the event on a subclass and see if it works?
If it does, then it is probably a bug, please log the bug in Eclipse Bugzilla.
Another workaround would be to use an entity listener.

Nhibernate: Get real entity class instead of proxied class [duplicate]

This question already has an answer here:
NHibernate Get objects without proxy
(1 answer)
Closed 2 years ago.
Is there a way to make nhibernate return my class instead of its proxy class? I dont mind if it's not lazy or cant be updated.
You can unproxy class with this code
session.PersistenceContext.Unproxy(proxiedInstance)
You should define this in your mapping, by defining lazy="false"
<class name="MyEntity" table="MyTable" lazy="false">
</class>
You can use following code to get real object
InstanceType instance;
if (proxiedInstance is INHibernateProxy)
{
var lazyInitialiser = ((INHibernateProxy)proxiedInstance).HibernateLazyInitializer;
instance = (InstanceType)lazyInitialiser.GetImplementation();
}
I'm using AutoMapper to achieve something similar in Entity Framework.
var nonProxiedInstance = Mapper.DynamicMap<YourType>(proxiedInstance);
That would work if you do not have navigation properties. Otherwise, you'll need to configure a mapping to ignore those properties.
Note: This is (obviously) an inefficient solution.
You can use the technique described in http://sessionfactory.blogspot.com/2010/08/hacking-lazy-loaded-inheritance.html (you'll need to do it recursively)
session.PersistenceContext.Unproxy(proxiedInstance) will not unproxy the associations. Also the no-proxy lazy loading does the same thing.
Disabling lazy loading is not a good idea and AutoMapper would navigate all the properties and trigger the loading mechanism.
IUnitOfWork.Unproxy from the NHUnit package could be used to unproxy the object and it's relations. This method will not initialize any proxy objects by mistake.

FluentNhibernate dynamic runtime mappings

I am building a framework where people will be able to save items that the created by inheriting a class of mine. I will be iterating over every type in the appdomain to find classes that I want to map to nhibernate. Every class that I find will be a subclass of the inherited type.
I know how to create sub types in FluentNhibernate, but every sub type requires its own ClassMap class. Since I won't know these untill runtime, there is no way I can do that.
Is there a way that I can add mappings to fluent nhibernate?
Note, I know this is possible without fluent nhibernate using the Cfg class, but I don't want to manage the same code two different ways.
something along the lines
Type classToMap = GetClassToMap();
var subclassmap = typeof(SubClassMap<>).MakeGenericType(classToMap);
foreach(var item in classToMap.GetPropertiesToMapSomehow())
{
var expression = // build lambda of property
subclassMap.Map(expression).Column("col") ...
}
config.Add(subclassmap) // NHibernate.Cfg.Configuration
There was support for this at once time, and the api is still there, but it is now depricated.