Exclude property from INSERT command in nhibernate - nhibernate

I have an entity with a property which I wish to be readonly - meaning that when I insert this entity to the DB, SqlServer will generate the property's value automatically so I need nhibernate to ignore this property when executing the INSERT command but retrieve it when selecting the entity.
Important note: this property isn't ID! I don't want NHibernate to initialize it using generator, SqlServer will do it by itself.
And another note: I use configuration mapping so no fluent mapping solutions please.

That functionality is supported. There are two attributes:
<property name="GeneratedBySql" insert="false" update="false" />
The same could be applied even for reference mapping
<many-to-one name="ReferenceGeneratedBySql" insert="false" update="false" />
If we want to use Mapping-by-Code we do have the same in places, see:
Mapping-by-Code - Property (by Adam Bar)
Snippet cited:
Property(x => x.Property, m =>
{
m.Column("columnName");
...
m.Update(false);
m.Insert(false);

Related

Mapping inherited class with nhibernate hbm

I Have 2 classes of the same table.
one class, "Entity", contains properties x,y,z from table ENTITY
and the derived class, "ExtendedEntity" contains some more properties (collections - relations to other tables).
I want to map both of them but i couldn't find a way to map subclasses without using discriminator (I dont need one, sometimes i want to select the Entity object and sometimes the ExtendedEntity).
does anyone has any idea?
(I tried to map the ExtendedEntity by copying the Entity mapping and adding the new properties, but now when i want to get the Entity object it brings me ExtendedEntity).
Thanks!
Taking into account the first sentence of your question:
I Have 2 classes of the same table.
It means that there is only one table ("ENTITY"). If this is true, there do not have to be, and even should not be any inheritance, if no discriminator exists. If both entities will be related to all rows, then (instead of inheritance) we need laziness. And only one Entity profiting from the native NHibernate behavior: having lazy properties. And even more, to optimize some queries - the Projections could be used.
But again, my suggestion could be correct only if I do understand your scenario correctly: the two entities were introduced only to reduce workload; but both target all rows in one table.
The mapping for the only class
<class name="Entity" table="ENTITY" lazy="true">
<id name="ID" column="Entityd">
<generator class="native"></generator>
</id>
<!-- standard default always loaded properties -->
<property name="Code" />
<property name="Name" />
<!-- only if accessed, lazily loaded properties -->
<many-to-one lazy="proxy" name="Currency" column="CurrencyId" cascade="none" />
<property lazy="true" name="Image" column="ImageBinary" />
...
Having this mapping we can get first 5 Entities
var list = session.CreateCriteria<Entity>()
.SetMaxResults(5)
.List<Entity>();
And SQL statement generated will be:
SELECT TOP 5 this_.EntityId as EntityId3_1_
, this_.Code as Code3_1_
, this_.Name as Name3_1_
FROM ENTITY this_
And we can even reduce it with projections
var propertyList = NHibernate.Criterion.Projections.ProjectionList();
// projection properties
propertyList.Add(NHibernate.Criterion.Projections.Property("ID"));
propertyList.Add(NHibernate.Criterion.Projections.Property("Code"));
var projected = session.CreateCriteria<Entity>()
.SetMaxResults(5)
.SetProjection(propertyList)
.SetResultTransformer(new NHibernate.Transform
.AliasToBeanResultTransformer(typeof(Entity)))
.List<Entity>();
In this case is the SQL Select even smaller. If the ID and Code would be enough..
SELECT TOP 5 this_.Code as y0_
, this_.EntityId as y1_
FROM ENTITY this_
So, in case I read your question correctly, in your scenario solution would not be in inheritance but in NHibernate native laziness
NOTE: there could be ExtendedEntity derived from Entity even in this scenario. But not for inheritance via NHibernate mapping but for the Projections Transformation. Some properties from many-to-one properties could be projected this way...

Could not find the property - exception after switching from NHibernate 3 to 3.3.1

I have a class with a field:
protected DateTime insertDate;
This is mapping for this fiels:
<property name="InsertDate" access="field.camelcase" update="false" />
This field is set when with ctor
public DocuBase(DateTime insertDate)
and is persisted only when row is added to the database. I don't need property for it at all, no setter & no getter. I worked in NHibernate 3.
And now, I've moved from NHiberbate 3 to NHibernate 3.3.1, and I get this exception when session factory is created:
Could not find the property 'InsertDate', associated to the field
'insertDate', in class 'XXXX'
Why is is happening & how can I change mapping in order to get rid of the exception?
EDIT: Below answer is completly correct. But for those of you that don't need/don't want to have a property, and only field, there's another solution:
set name attribute to field name (in my case it is insertDate) and remember to have correct column name
<property name="insertDate" column="InsertDate" access="field.camelcase" update="false" />
It is case sensitivity, this will work.
<property name="insertDate" column="InsertDate" update="false" />
Looks like in release 3.1.0, there was a breaking change
NH today accepts code below. It would be better if this would throw - it causes problem when configurate NH (or 3rd party tools) other ways than by hbm, using the property name (or memberinfo) of the public interface.
[hbm]
<property name="Name" access="field.camelcase" />
[code]
string name;
public virtual string SomeThingCompletelyDifferent{
get {return name;}
set{name=value;}
}
Note: This will be a breaking change.
ps - updated answer to remove reference to use Property with private set as this was not what was being looked for and above breaking change is more relevant.

Filter entities on mapping level in NHibernate

Let's say that I have and database table called People, and entity People. Let's say that I need a quick way to remove a subset of people from displaying everywhere in application. So I add IsDeleted column to People table, and set values in that column to 1.
In Entity Framework there's a mechanism that specifies that for instans of entities with value in column IsDeleted set to 1 shouldn't be fetched and mapping framework filters data automatically. Is is possible to achieve with NHibernate?
You can define where attribute in your class mapping.
where (optional) specify an arbitrary SQL WHERE condition to be used
when retrieving objects of this class
<class ... where="IsDeleted = 0">
If you are using Fluent NHibernate then just define this in mapping class:
Where("IsDeleted = 0");
NH's mapping by code should be similar to Fluent NHibernate's mapping.
You can create abstract class, e.g. PeopleBase, from which your People class will be derived and map your entity to it.
After that you can use discriminator like this (didn't check for correctness, but it should work):
<class name="YourNamespace.PeopleBase,YourNamespace" table="People">
// ...
<discriminator column="IsDeleted" type="boolean" />
// Properties...
// ...
<subclass name="YourNamespace.People, YourNamespace" discriminator-value="false">
</subclass>
</class>
In order to achieve what I wanted, I've created base class + two subclasses. This is the configuration:
subclasses with discriminator-value:
<subclass name="People" discriminator-value="null">
</subclass>
<subclass name="PeopleHistory" discriminator-value="not null">
<property name="MasterRowId" />
</subclass>
discriminator in base class:
<discriminator column="MasterRowId" />

How to map NHibernate custom collection with fluentNHibernate?

I am trying to map the collection for two days without success. I also read all possible articles and forums but still down there. Ok, here is the problem:
1) The collection class contains a private field "_internalCollection" which is mapped with NHib.
2) The holding entity should expose the collection trough readonly property.
3) I want to avoid implementing NHibernate interface IUserCollectionType!!!
I did this with xml mapping and it work great. The WarehouseEntity is a collection Item. Warehouses is a readonly property in OrgEntity class.
<component name="Warehouses" class="Core.Domain.Collections.EntitySet`1[Core.Domain.OrgStructure.IWarehouseEntity,Core],Core">
<set name="_internalCollection" table="`WAREHOUSE`" cascade="save-update" access="field" generic="true" lazy="true" >
<key column="`WarehouseOrgId`" foreign-key="FK_OrgWarehouse" />
<!--This is used to set the type of the collection items-->
<one-to-many class="Domain.Model.OrgStructure.WarehouseEntity,Domain"/>
</set>
</component>
Any idea how can I do it with fluent NHibernate?
EDIT: Core.Domain.Collections.EntitySet`1 is base collection class. It provides basic functionality for working with collections and can fit any class which is IEntity interface.
Try:
HasMany(x => x.Warehouses)
.AsSet().KeyColumn("WarehouseOrgId")
.Access.CamelCaseField(Prefix.Underscore)
.ForeignKeyConstraintName("FK_OrgWarehouse");
Edit: I missed a key part of the question so here's another try:
Component(x => x.Warehouses, m =>
{
m.HasMany<Warehouse>(Reveal.Member<EntitySet<IWarehouseEntity>>("_internalCollection")
.AsSet().KeyColumn("WarehouseOrgId")
.ForeignKeyConstraintName("FK_OrgWarehouse");
});
I'm sure that's not it but hopefully it puts you on the right path. Also have a look using ComponentMap.
My advice is to avoid custom collections entirely. I replaced all of ours with extension methods on IEnumerable<T>.

NHibernate custom collection type

I'm having an entity object called Patient and this entity is having a property called Visits which is of type VisitsCollection.
VisitsCollections is a child class of IList<Visit> but it also adds some custom logic to the collection (like auto ordering, some validation, notifications, etc..).
I need to use the custom collection type as it adds some data to the entities that are added to the collection and performs some other paperwork transparently.
Now I want to map that in NHibernate, so I've created:
<list name="Visits" lazy="true" fetch="select">
<key foreign-key="PatientId" />
<index column="Timestamp" />
<one-to-many class="Visit" not-found="ignore"/>
</list>
I'm getting an exception:
Unable to cast object of type 'NHibernate.Collection.PersistentList' to type '...VisitsCollection'
Whenever I'm accessing the visits property.
I've also tried to map it this way:
<list name="Visits" lazy="true" fetch="select" collection-type="VisitsCollection">
<key foreign-key="PatientId" />
<index column="Timestamp" />
<one-to-many class="Visit" not-found="ignore"/>
</list>
but still, I'm getting this exception:
Custom type does not implement UserCollectionType: .....VisitsCollection
I don't want to inherit my VisitsCollection from any NHibernate type as the collection class is part of a framework that I want it to be DAL-agnostic (as it will be used in many scenarios - not only with a database).
Any ideas on how to map this, preserving the structure of my code?
Thanks in advance.
I never use custom collection types, mainly because I'm lazy. NHibernate wants you to use a IUserCollectionType I believe, which requires a bit of plumbing.
Rather than that, my first stop would be to look at using extension methods as discussed by Billly McCafferty. But you have code written so...
Alternatively, you could map your collection as a component as discussed here by Colin Jack. This might be easier for your scenario?
Also check this SO thread.
I also vote up not to use custom collections. Anyway, you can do it via component.
<component name="Warehouses" class="Core.Domain.Collections.EntitySet`1[Core.Domain.OrgStructure.IWarehouseEntity,Core],Core">
<set name="_internalCollection" table="`WAREHOUSE`" cascade="save-update" access="field" generic="true" lazy="true" >
<key column="`WarehouseOrgId`" foreign-key="FK_OrgWarehouse" />
<!--This is used to set the type of the collection items-->
<one-to-many class="Domain.Model.OrgStructure.WarehouseEntity,Domain"/>
</set>
How to map NHibernate custom collection with fluentNHibernate?
Just for reference, here is how you could do it using FluentNHibernate
Whether we should or should not create a custom collection type is a separate topic IMHO
public class PatientOverride : IAutoMappingOverride<Patient>
{
public void Override(AutoMapping<Patient> mapping)
{
mapping.Component(
x => x.Visits,
part =>
{
part.HasMany(Reveal.Member<VisitsCollection, IEnumerable<Visit>>("backingFieldName")) // this is the backing field name for collection inside the VisitsCollection class
.KeyColumn("PatientId")
.Inverse(); // depends on your use case whether you need it or not
});
}
}