Table of contents
- 1 General questions
- 1.1 What is ActiveRecord?
- 1.2 What is Castle ActiveRecord?
- 1.3 How does it differ from pure NHibernate usage?
- 1.4 My text columns are being truncated
- 1.5 My property name is a reserved word in my database
- 1.6 ActiveRecord throws an exception saying: Ambiguous column name 'Status'
- 2 Database related
- 2.1 Gaining access to the underlying database connection
- 3 Lazy loading
- 3.1 How to enable lazy loading
- 3.2 What 'Failed to lazily initialize a collection - no session' error means?
- 3.3 Lazy loading in web applications
- 3.4 Lazy loading in desktop/winforms applications
- 4 Changes to objects are persisted without an explicit call to the Save() method
FAQ
This page has a list of frequently asked questions.
General questions
What is ActiveRecord?
ActiveRecord is a well-known pattern described in Patterns of Enterprise Application Architecture. Basically all static methods act on the whole set of records, while instances represents each row.
Read more about the pattern:
- Patterns of Enterprise Application Architecture Catalog - Active Record pattern
- Wikipedia Active Record article
What is Castle ActiveRecord?
Castle ActiveRecord is an implementation of the ActiveRecord Pattern inspired by Rails' ActiveRecord, which relies on NHibernate to perform the actual mapping (as you see we don't suffer from Not-invented-here anti-pattern).
How does it differ from pure NHibernate usage?
Castle ActiveRecord was built on top of NHibernate. It offers:
- Fast development (it handles the mapping and infers as much as it can so you don't have to dig into documentation or deal with tons of xml files every time something changes on your schema)
- Predefined common methods like Create, Update, Save, Delete
- Easy to implement method like Find, FindAll, FindByName. (Predefined if you use ActiveRecordBase
) - Session and transaction scopes that abstracts the ISession offering a more natural idiom
By using pure NHibernate, you have more control over more complex mappings. However, using Castle ActiveRecord is a guarantee to boost your productivity.
My text columns are being truncated
Add ColumnType="StringClob" parameter to your Property attribute. For example:
[Property(ColumnType="StringClob")] public String Contents { get { return _contents; } set { _contents = value; } }
This tells NHibernate to map the string to a Text type rather than a nvarchar(4000) type.
My property name is a reserved word in my database
Add explicit column name parameter to your Property attribute and quote it with backticks. For example:
[Property("`User`")] public String User { get { return _user; } set { _user = value; } }
This tells NHibernate to quote the column name when querying the database.
ActiveRecord throws an exception saying: Ambiguous column name 'Status'
A column named Status is returned internally by NHibernate. Try renaming your column in the database.
Database related
Gaining access to the underlying database connection
This is possible using the session holder:
using Castle.ActiveRecord; ... // Expects a root type ISession sess = ActiveRecordMediator.GetSessionFactoryHolder(). CreateSession(typeof(ActiveRecordBase)); // Now you can use sess.DbConnection ActiveRecordMediator.GetSessionFactoryHolder().ReleaseSession(sess);
Try to use a finally block to release the session. Do not invoke ISession.Close or ISession.Dispose
Lazy loading
How to enable lazy loading
Check the documentation on lazy load.
What 'Failed to lazily initialize a collection - no session' error means?
Means that there is no session available. Check the documentation on lazy load in order to know how to make it work properly.
Lazy loading in web applications
Check the documentation on ActiveRecord in web applications.
Lazy loading in desktop/winforms applications
Start the ActiveRecord during application start up. You can create a readonly SessionScope and flush it in appropriate moments using SessionScope.Current.Flush. Check the manual for further reference.
Changes to objects are persisted without an explicit call to the Save() method
This commonly happens if you are using SessionScope per request pattern. Basically this is an expected NHibernate behavior, although the first time you experience it, it can seem very confusing.
From: NHibernate Users FAQ
"When an object is loaded by NHibernate the ISession keeps a snapshot of the state of your object. When you Flush() the ISession NHibernate compares that snapshot to the current state of the object. The appropriate changes are written to the database."
So when the Session is Flush()ed any changes to an objects state are written to the database. The next question is when does a Flush() occur? Well according to Tobins' NHibernate FAQ it can occur at a number of different (and possibly unexpected) places.
If this is really bothering you, you can create a readonly SessionScope. In this case it is up to you to Flush it. You can read more about the SessionScope on ActiveRecord documentation.