Fluent mapping is the namesake mapping style that Fluent NHibernate uses. It's a fluent interface that allows you to map your entities completely in code, with all the compile-time safety and refactorability that brings.
- Fluent Nhibernate Composite Key Generator Download
- Fluent Nhibernate Tutorial
- Nhibernate Classmap
- Sql Composite Key Definition
The getting started guide has a good introduction to mapping with the fluent interface, and the detail provided here builds upon that introduction.
ClassMap
is the basis of all your mappings, you derive from this to map anything.You map your entities' properties inside the constructor.
'Syntax note:' Every mapping inside a
ClassMap
is built using lambda expressions, which allow us to reference the properties on your entities without sacrificing compile-time safety. The lambdas typically take the form of x => x.Property
. The x
on the left is the parameter declaration, which will implicitly be of the same type as the entity being mapped, while the x.Property
is accessing a property on your entity (coincidentally called 'Property' in this case). You'll quickly get used to these lambdas, as they're used everywhere in Fluent NHibernate.Once you've declared your
ClassMap
you're going to need to map the properties on your entity. There are several methods available that map your properties in different ways, and each one of those is a chainable method that you can use to customise the individual mapping.- I am new to fluent NHibernate. Now I face one problem with mapping composite keys. Can anyone point out the URL or sample please?
- Key Column Name AttributeDefId, ObjectDefId We will then generate suitable composite mappings in XML or Fluent NHibernate as required. The nightly build will be available from about 1200 GMT and you will be able to get it from the Downloads page. Let us know how it goes!
Every mapping requires an Id of some kind. The Id is mapped using the
Id
method, which takes a lambda expression that accesses the property on your entity that will be used for the Id. Depending on the return type of the property accessed in the lambda, Fluent NHibernate will make some assumptions about the kind of identifier you're using. For example, if your Id property is an int
, an identity column is assumed. Similarly, if you use a Guid
then a Guid Comb is assumed.Note that the property you supply to
Id
can have any name; it does not have to be called 'Id,' as shown here.Jul 11, 2012 This example demonstrates how to work on mappings with associations for legacy database tables designed purely using multiple primary keys/composite keys. The article NHibernate and Composite Keys by Anne Epstein provides a thorough explanation on fundamental composite keys mapping and supporting lazy loading by declaring the composite keys as a class object.
That's the most common scenario for mapping your Id. Customisations can be done by chaining methods off the
Id
call. For example, if the column to which the Id
property was to be mapped were not called Id
, we could use the Column
method to specify the name. For explicitly specifying the identity generator, you could use the GeneratedBy
property.In this example we're specifying that the Id property is mapped to a PersonId column in the database, and it's using an assigned generator.
Fluent NHibernate's interface is designed for discoverability. Everything you need should be easy to find 'under' the declaring method using method chains.
Property mappings make up a large amount of any mapped domain. Fortunately, they're just as easy to create as identities, except we use the
Map
method.That's all you need for most situations. Fluent NHibernate knows what the return type of your property is, and assumes that the column it's mapping against will have the same name as the property itself. There are numerous customisations available through methods chained from the
Map
call. For example, if you're generating your schema you may want to specify whether the column itself is nullable, you can do that by using the Nullable
method and (optionally) the Not
operator property.If you need to map private properties, you can explore your options fluent mapping private properties.
Access strategies
Access strategies are NHibernate's way of knowing how to get or set the values in your entity. Fluent NHibernate can detect what access strategy to use, so most of the time you won't need to specify it.
For example, private field via public property:
For example, read-only auto-property:
Except in the most basic of scenarios, you'll need to map relationships among entities. These will typically take the form of many-to-one, one-to-many, and many-to-many relationships. For better or worse, we tend not to refer to these by their database design names: we aren't database administrators, after all. Instead, we refer to them as References, HasMany, and HasManyToMany, respectively. We'll go into each in more detail next.
References / many-to-one
References is for creating many-to-one relationships between two entities, and is applied on the 'many side.' You're referencing a single other entity, so you use the
References
method. #HasMany / one-to-many is the 'other side' of the References relationship, and gets applied on the 'one side.'Let's map a relationship between a book and its author.
In domain terms, we have an
Author
which may be associated with any number of Book
s, and Book
s, each of which can be associated with a single Author
.In database terms, we'd have a book table with a foreign key column referencing the primary key of an author table.
To create the references relationship in your
Book
#ClassMap, add the following call in the BookMap
constructor:That's it, you've now created a references relationship between
Book
and Author
. The foreign-key is assumed to be named Author_id
in your book table, unless you have a different Conventions in place or override the name by using the Column
method.As with all other fluent mappings, you can chain calls to customise the reference relationship. For example if you wanted to specify the cascade strategy you'd use the
Cascade
property.HasMany / one-to-many
HasMany is probably the most common collection-based relationship you're going to use. HasMany is the 'other side' of a #References / many-to-one relationship, and gets applied on the 'one side' (one author has many books). Now let's map the author side of the relationship we started above. We need to join into the books table returning a collection of any books associated with that author.
We use the
HasMany
method in the AuthorMap
constructor to map this side of the relationship:As with References, the foreign-key defaults to
Author_id
, and you can override it with the KeyColumn
method or change the default behaviour with a Conventions.There are a few different types of collections you can use, and they're all available under the
HasMany
call.Collection types
Fluent NHibernate does its best to detect the collection type for your collections. For example, an ISet<T> will be mapped as a Set for NHibernate.
As of release 1.2, Fluent NHibernate can also detect collection types for collections that are exposed by an IEnumerable<T>.
For example:
HasManyToMany / many-to-many
HasManyToMany works exactly the same as #HasMany / one-to-many, except the underlying database structure to which it maps is different.
There are a few different types of collections you can use, and they're all available under the HasManyToMany call.
HasOne / one-to-one
HasOne is usually reserved for a special case. Generally, you'd use a #References / many-to-one relationship in most situations (see: I think you mean a many-to-one). If you really do want a one-to-one, then you can use the
HasOne
method.To specify the foreign key, you can use the
PropertyRef()
method. Additionally, if you are using References()
to specify the bi-directional relationship on the other end of the relationship, be sure to use the .Unique()
mapping modifier to effectively specify that this is a one-to-one relationship.In the example below, we are mapping the relationship between a Car entity and a SteeringWheel entity. For our business rules, a Car will only ever have one SteeringWheel so we would map it like so:
Any
Any mappings are another special case, and you really only should use them if you know what you're doing. To quote the NHibernate documentation:
The
<any>
mapping element defines a polymorphic association to classes from multiple tables. This type of mapping always requires more than one column. The first column holds the type of the associated entity. The remaining columns hold the identifier. It is impossible to specify a foreign key constraint for this kind of association, so this is most certainly not meant as the usual way of mapping (polymorphic) associations. You should use this only in very special cases (eg. audit logs, user session data, etc).There are three things you need to provide to be able to map using an Any:
- A column that holds the type of the entity,
- At least one column holding the identifier value, and
- A type for the identifier itself.
You can specify these using the
EntityTypeColumn
, EntityIdentifierColumn
, and IdentityType
methods respectively.![Fluent Nhibernate Composite Key Generator Fluent Nhibernate Composite Key Generator](/uploads/1/2/6/0/126094386/628590724.png)
Components are a clever way of mapping a normalised data model into a more reasonable object model. You may have a customer table that has a series of address columns, ideally you'd want the address columns to be mapped into an Address object, rather than just being properties on a Customer; you can do that with components.
The
Component
method takes two parameters, rather than just one like the rest of the methods you've seen so far. The first parameter is a property accessor lambda, like all the other methods, and the second one is another lambda (quite often referred to as a nested-closure in these situations) that defines a new scope for defining the mappings of that particular sub-part (in this case the component).As you can see, the first parameter references the
Address
property on our entity, which is the property that holds our component. The second property is where we define what makes up the component. The main difference in this lower scope is that you have to use the m
instance to access the available methods; you don't have to call it m
, but we are for brevity.In this case we've mapped a component (stored in the Address property), that's made up of three properties (Number, Street, and PostCode); these properties are stored in the same table as the parent entity in a normalised fashion.
ComponentMap
Note: ComponentMap's are incompatible with the automapper. If you're using the automapper then your ComponentMap's will be ignored.
If you have a particular component that occurs regularly in your entities, you can abstract the mappings into a single
ComponentMap
definition.Using the example of an
Address
again, it wouldn't be surprising to find that multiple entities had addresses; perhaps Person
, and Company
.Normally you would need to define an inline component mapping for each occurrence of
Address
, using the Component(property, mapping)
method, even though they'd be identical.However, using the
ComponentMap
, you can define your component mapping in a single location.With that created, you only need to signify that your properties are a component from your entity mappings by using the new
Component(property)
overload that takes a single parameter (it doesn't take a closure for defining the body like the other Component
methods).Column names
If you have multiple instances of the same component in an entity, say
WorkAddress
and HomeAddress
, you'll need to supply a prefix for the columns. This is because the column names are, by default, based on the properties within the component, so you'd end up with two Streets, etc...To supply a prefix, chain a call to
ColumnPrefix
from your Component(property)
call.'Note:' this only works for
ComponentMap
-based components.Fluent Nhibernate Composite Key Generator Download
This would create WorkStreet, WorkCity, WorkPostCode columns.
Note: SubclassMap's are incompatible with the automapper. If you're using the automapper, your SubclassMap's will be ignored. See Auto mapping#Inheritance for guidance on dealing with subclasses with the automapper.
Subclasses work in a very similar way to #ClassMap, in that you create a derived class into which you put your mappings, but here you use
SubclassMap
instead of ClassMap
.There are two strategies for mapping inheritance hierarchies in Fluent NHibernate: table-per-class-hierarchy and table-per-subclass, the former being a subclass and the latter a joined-subclass. This means that you can define one table to hold all subclasses (with 1 or more columns used to identify the specific type for each row), or you can define separate tables for each subclass.
'Note:' For multiple discriminator columns use a
DiscriminateSubClassesOnColumn(').Formula([insert custom sql here])
Table-per-subclass is the default mapping for subclasses, so unless you say otherwise you'll have a separate table for each subclass. The parent mapping dictates what the subclass mapping strategy will be, by either specifying or not specifying a discriminator (discriminators are required for table-per-class-hierarchy).
We'll use the following two classes for examples:
If you wanted to map this as a table-per-subclass, you'd do it like this:
That's all there is to it,
Parent
and Child
are now mapped as subclasses. When Fluent NHibernate finds ChildMap
, it knows that it's a subclass of Parent
.If you wanted to do a table-per-class-hierarchy strategy, then you just need to specify the discriminator column in your
ClassMap
.The only difference is that we're now calling
DiscriminateSubclassesOnColumn
in ParentMap
with a 'type'
parameter. This parameter specifies the name of the column in the table that identifies which subclass the data in a given row represents.The <generator> class is a sub-element of id. It is used to generate the unique identifier for the objects of persistent class. There are many generator classes defined in the Hibernate Framework.
All the generator classes implements the org.hibernate.id.IdentifierGenerator interface. The application programmer may create one's own generator classes by implementing the IdentifierGenerator interface. Hibernate framework provides many built-in generator classes:
- assigned
- increment
- sequence
- hilo
- native
- identity
- seqhilo
- uuid
- guid
- select
- foreign
- sequence-identity
1) assigned
It is the default generator strategy if there is no <generator> element . In this case, application assigns the id. For example:
2) increment
It generates the unique id only if no other process is inserting data into this table. It generates short, int or long type identifier. If a table contains an identifier then the application considers its maximum value else the application consider that the first generated identifier is 1. For each attribute value, the hibernate increment the identifier by 1. Syntax:
3) sequence
It uses the sequence of the database. if there is no sequence defined, it creates a sequence automatically e.g. in case of Oracle database, it creates a sequence named HIBERNATE_SEQUENCE. In case of Oracle, DB2, SAP DB, Postgre SQL or McKoi, it uses sequence but it uses generator in interbase. Syntax:
For defining your own sequence, use the param subelement of generator.
4) hilo
It uses high and low algorithm to generate the id of type short, int and long. Syntax:
![Fluent Nhibernate Composite Key Generator Fluent Nhibernate Composite Key Generator](/uploads/1/2/6/0/126094386/775109008.png)
5) native
Fluent Nhibernate Tutorial
It uses identity, sequence or hilo depending on the database vendor. Syntax:
6) identity
Nhibernate Classmap
It is used in Sybase, My SQL, MS SQL Server, DB2 and HypersonicSQL to support the id column. The returned id is of type short, int or long. It is responsibility of database to generate unique identifier.
7) seqhilo
It uses high and low algorithm on the specified sequence name. The returned id is of type short, int or long.
8) uuid
It uses 128-bit UUID algorithm to generate the id. The returned id is of type String, unique within a network (because IP is used). The UUID is represented in hexadecimal digits, 32 in length.
9) guid
It uses GUID generated by database of type string. It works on MS SQL Server and MySQL. |
10) select
It uses the primary key returned by the database trigger. |
Sql Composite Key Definition
11) foreign
It uses the id of another associated object, mostly used with <one-to-one> association. |
12) sequence-identity
It uses a special sequence generation strategy. It is supported in Oracle 10g drivers only. |
Next TopicDialects In Hibernate