Does anyone know how the following HBM property mapping could be translated to Fluent?
<typedef class="uNHAddIns.UserTypes.EncryptedString, uNHAddIns" name="Encrypted">
<param name="encryptor">uNhAddIns.UserTypes.uNHAddinsEncryptor, uNhAddIns</param>
<param name="encryptionKey">myRGBKey</param>
</typedef>
It doesn't have to work specifically for the EncryptedString type, but I need to know if it's possible to add params to CustomType mappings in Fluent.
It appears that this is not supported by Fluent NHibernate at this time. Here is a link to the issue in GitHub:
https://github.com/jagregory/fluent-nhibernate/issues/193
Related
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.
NHibernate question:
Say I have a SQL table Person and it has a Picture column ( OLE Object ) . I have a class Person and it has : byte[] Picture attribute.
Is it possible to map like this ?
<property name = "Picture" column = "Picture" type = "System.Byte[]" lazy="true" />
Does the "lazy" keyword have any effect on properties or can it only be used when working with collections / bags etc?
It appears that this feature just landed in the NHibernate trunk:
http://ayende.com/Blog/archive/2010/01/27/nhibernate-new-feature-lazy-properties.aspx
I have not found any way to get this to work, but the following two ways may help you around the problem you imply:
You can map two classes for the same table, one including the byte array, the other not.
You can include a many-to-one property mapping to the same table, where the child class has the byte array included, and you then access the binary using Person.PersonPicture.Picture rather than just Person.Picture; the intermediate class can now be lazy loaded.
Neither is ideal, but they do work. Short answer - collections and many-to-one properties can be lazy loaded, straight properties not.
how exactly I can use public methods (non-virtual) with NHibernate?
I have this code:
public string crewNumber
{
get
{
return this.crewNumberField;
}
set
{
this.crewNumberField = value;
}
}
Note all my classes, properties, methods and interfaces are auto-generated and I do not want to change them manually.
Above code is producing this error:
The following types may not be used as
proxies: ... method get_crewNumber
should be 'public/protected virtual'
I see that it shold be possible to use simple public only properties here:
In our example above, we've made the
properties and the constructor public
- but that's not a requirement for NHibernate - it can use public,
protected, internal, or even private
properties to persist your data.
How do I turn off this virtual by default?
It's driving me crazy. I am really tempted here to drag one data adapter in visual studio and to end this ridiculous situation once and for all ;-)
Thanks
Specify that dynamic proxies should not be used for that class, by specifying lazy=false on the class-mapping.
Like this:
<class name="MyClass" table="MyTable" lazy="false">
</class>
This means offcourse that you cannot use dynamic proxies with NHibernate.
To be more clear:
- when you retrieve an instance of your class, which is able to use dynamic proxies, you'll recieve an 'empty instance'. That is, NHibernate will not fetch the data from the DB yet. You'll get an object who'se Id will be populated, but the other properties are not. Only when you access a property, then NHibernate will load the data from the DB. That's the reason why the properties need to be virtual, because NHibernate will create a subclass of your class internally, and override the properties so that it can achieve this behaviour.
I always specify 'lazy=false' on my class-mapping, since I don't want to have virtual properties for a reason that is infrastructure-related, instead of 'domain-related'.
(Note that this has nothing to do with lazy loading of associations; it is still possible to have them lazy loaded when you do not use dynamic proxies).
Put lazy="false" at the class mapping:
<class name="MyClass" table="MY_TABLE" lazy="false">
I have a scenario that i want to add some standard properties to my entities. Meaning that i will have e.g. 1 int and 2 string properties applied to all relevant entities. I have over 100 mapping files and most but not all will be hosts to these new properties. In the classes its easy to define this; in the mappings however i've found no reference other than creating a utility or xslt and applying that (How to define reusable <generator> elements in hibernate mapping).
However i want to be able to add/modify/remove properties from this "standard" mapping.
thx for any replies
Edit1: an example of the mapping i want to add
<property name="TimeOfEdit" column="TimeOfEdit" type="DateTime" not-null="true"/>
<many-to-one name="EditedBy" column="FK_EditedBy" cascade="save-update" not-null="true" />
Edit2:
I removed the accepted solution because with NH 2.1.1 XML Entities are not working (NH-1236) and NH will throw a "DTD is prohibited in this XML document"
It depends on how these properties are implemented in your classes.
If they are all defined in a base class or interface, you could map them once in the base class or interface, and derive using union-subclass. There are some limitations. Read this chapter in the NHibernate documentation about it.
If you decide to put them together into a class, you could map them as a user type. This will be similar to a component, but you could specify some things like type names, lengths and others in the user type. You still need to specify each column name.
There is another option: you could use XML entities. This is a rather primitive feature from XML which is supported by NHibernate. Read this chapter in the NH reference documentation where it is mentioned.
Creating a special code generator for your specific case is your only option.
Option 1:
-Define these 3 properties in a base class
-have your entities inherit from this base
-set up 'table per class hierarchy'
Option 2:
-Define these 3 properties as a component.
-You can have the mapping for these 3 properties in one file that is reused.
You might take a look at fluentNHibernate, It will simplify the mapping work for you. With With auto mapping you may only need an abstract base class to define these properties.
It seems that the only to do this, is to use Dynamic Mapping (http://ayende.com/Blog/archive/2008/05/01/Dynamic-Mapping-with-NHibernate.aspx)
as such since i've already defined an interface that my entities will use for the new properties (lets say IAuditable) its just a matter of running the appropriate code at the NH-session initialization
Configuration cfg = new Configuration() Mappings mappings = cfg.CreateMappings();
foreach (var persistentClass in mappings.Classes)
{
if (persistentClass.MappedClass is IAuditable)
{
...
}
}
and then
cfg.BuildSessionFactory();
to have it wired up and ready to be used
for about 85 classes the performance impact is negligible
Edit: Ryan raised a good point. I specifically want to be able to map to and from while still storing human-readable values in the database. That is, I don't want a bunch of enumeration integers in my database.
According to the documentation you can either leave the type attribute of the property in your mapping file blank or you define it and specify the class name of the enumeration.
Another way would be to convert the enumeration to an int and use the int as the mapped type.
You have to implement a custom IUserType. See this post.
I've never used NHibernate, but can't you just set the SQL datatype to int?
I think you can just set the type to string:
<property name="EnumProperty" Type="string" Length="50" NotNull="true" />