Is it possible to use IUserType as an Id in Fluent Hibernate mapping? - fluent-nhibernate

I have a IUserType defined class and I want to use it as an Id of a table. When using Native generator I get an exception
InnerException: System.InvalidOperationException
Message=Identity type must be integral (int, long, uint, ulong)
Source=FluentNHibernate
My next step is to investigate custom generators but I wanted to verify that its possible to use user types as Ids.
So, can it be done?

Related

Spring4D Marshmallow and TGuid fields

how could I use TGuid type fields together with the Marshmallow ORM? Methods like FindOne, for example, expect parameters of type TValue and when trying to use im TGuid, the error occurs: incompatible types: TValue and TGUID.
thanks.
some information or example of how to make such use.

Combine JsonDeserialize#contentAs with JsonDeserialize#contentConverter or JsonDeserialize#contentUsing for custom deserialization

In JsonDeserialize annotation documentation the contentAs field is supposed to define the "Concrete type to deserialize content".
I tried to use this in combination, with either a Converter (via contentConverter field of the same annotation) or a JsonDeserializer (via contentUsing field of the same annotation), by extending either StdConverter or StdDeserializer, respectively, in an attempt to create an agnostic custom deserializer.
I cannot find a way to access the JsonDeserialize#contentAs information inside any of these two classes.
I am aware that the classes I extend from have a type parameter, I just put an Object class there. Documentation states
contentAs Concrete type to deserialize content (elements of a Collection/array, values of Maps) values as, instead of type otherwise declared. Must be a subtype of declared type; otherwise an exception may be thrown by deserializer.
Apparently I am applying the #JsonDeserializer annotation on a Collection of some persistable Class. I want to deserialize each such object, solely by knowing its id. Well, if I could only get that very type I defined in the #JsonDeserializer#contentAs field...
Can anyone tell me if this is possible anyhow?
I managed to implement the agnostic deserializer withou the use of #JsonDeserializer#contentAs after all.
After reading the javadocs of com.fasterxml.jackson.databind.JsonDeserializer I concluded that my custom deserializer should implement the com.fasterxml.jackson.databind.deser.ContextualDeserializer interface.
Inside the implementation of ContextualDeserializer#createContextual(DeserializationContext ctxt, BeanProperty property)
I could finally get access to the class type of the content of the collection, which I applied the #JsonDeserialize annotation on,
by calling:
ctxt.getContextualType().getRawClass()
NOTE that the same call inside the implementation of com.fasterxml.jackson.databind.JsonDeserializer#deserialize(com.fasterxml.jackson.core.JsonParser, com.fasterxml.jackson.databind.DeserializationContext) returned null, hence the need of the aforementioned interface.
All I had to do then is store the returned class in a member field (of type Class< ? >) of the custom deserializer and use it in the execution of JsonDeserializer#deserialize()
The only thing that remains to check is whether an instance of this custom deserializer is shared between threads. I only did some minor checks; I used the same implementation for two different collections of different types. I observed that ContextualDeserializer#createContextual(DeserializationContext ctxt, BeanProperty property) was called once (among multiple deserialization invokations), for each distinct type that was going to be deserialized. After checking during debugging, it seems that the same deserializer object is used for the same type. In my case, since what I store in the member field is this type itself, I don't mind if the same deserializer is used for the same java type to be deserialized because they should contain the same value. So we 're clear on this aspect as well.
EDIT: It appears all I have to do is update the com.fasterxml.jackson.databind.deser.std.StdDeserializer#_valueClass value to the now known class. Since it is final and since the ContextualDeserializer#createContextual(DeserializationContext ctxt, BeanProperty property) returns a JsonSerializer object, which is actually used,
instead of returning "this" serializer I can create a new one, passing the discovered class in the constructor, which actually sets the StdDeserializer#_valueClass to the class I actually want, and I'm all set!
Finally, NOTE that I didn't have to use the #JsonDeserializer#contentAs annotationfield as I get the value from the ctxt.getContextualType().getRawClass() statement inside ContextualDeserializer#createContextual(DeserializationContext ctxt, BeanProperty property) implementation

Determine the type of a dynamic model

In NHibernate, you can map tables but without writing a class for them -- "dynamic models". These are returned as Hashtable instances.
If you connect an event listener, for example an IPreDeleteEventListener, you can receive PreDeleteEvents. These have:
object[] DeletedState
object Entity
object Id
IEntityPersister Persister
IEventSource Session
I see no way here to get the type of the object. Specifically, I want the entity-name of the <nh:class> (but table would be great, too).
It seems like there ought to be a way to get this, but I'm just not seeing it. I'm being told that an event fired on an entity, and being handed a Hashtable and Id but I can't figure out what type it is.
Is there some method I'm just missing? Or can anyone think of a usable workaround?
You can get the entity-name using the $type$ key on the dictionary/hashtable itself.
To get more granular details like table name, you'd probably have to find those in the runtime NHibernate configuration (looking up by the entity-name value).

NHibernate: projecting a subclass type of an entity

How do I query a class of a specific entity in NHibernate?
I basically want a projection that returns a System.Type of each row that matches criteria.
I have looked at Get subclass type from projection with NHibernate however when I create Projections.Property("alias.class") or Projections.Property("class"), I always get could not resolve property 'class'.
Projections.Property("class") is possible and it works, but only if the class has a discriminator.
I got an answer from person on my team (Denis Bykov).
Unfortunately I had hard time making him answer here so I can award him reputation.
I don't think this is possible using NHibernate directly; but consider adding the following to your base entity class (assuming you have one):
protected virtual Type GetTypeUnproxied() {
return GetType();
}
After you have queried your entities, you can interrogate this property to return the actual CLR type of the entity.
If you can't get access to the type through NHibernate for projection purposes, perhaps you can store the System.Type in a field using a custom user type. This should give you the exact functionality you require.

How do I map nested generics in NHibernate

In NHibernate you can map generics like this
<class name="Units.Parameter`1[System.Int32], Units" table="parameter_int" >
</class>
But how can I map a class like this?
Set<T> where T is a Parameter<int> like this Set<Parameter<int>>
My mapping hbm.xml looking like this fails
<class name="Set`1[[Units.Parameter`1[System.Int32], Units]],Units" table="settable"/>
I simplified my mappings a little to get my point accross very clearly. Basically I want NHibernate to map generic class which has has generic type parameter.
Want I understand from googling around is that NHibernate is not able to parse the name to the correct type in TypeNameParser.Parse() which result in the following error when adding the mapping to the configuration
System.ArgumentException: Exception of type 'System.ArgumentException' was thrown.
Parameter name: typeName#31
Anybody found a way around this limitation?
I think you'll have to map it as a custom type. See this article and google for IUserType.