Showing posts with label NHibernate. Show all posts
Showing posts with label NHibernate. Show all posts

Thursday, 17 November 2011

NHibernate - HQL - No Persister for xxx

Was getting strange error ' No Persister for System.String' when doing HQL query using a parameter.

Turned out it was because I was using SetEntity to assign the parameter value instead of SetString

All because of cutting and pasting!

Monday, 19 October 2009

NHibernate - Entity property is an Interface - mapping

If you have a class that maps to a table and a property of the class is an association to another table (i.e. 1:M Property) you may get the following error if the property is defined as an interface type:

 

NHibernate An association from the table XYZ refers to an unmapped class

 

This occurs because NHibernate will not have a mapping file for the interface type and cannot instantiate it because it is an interface. To fix the problem you need to include in the mapping file the actual class the property represents.

e.g.

 

IAccount MainAccount;

 

may map to

 

<many-to-one name="MainAccount" column="MainAccountID" class="BankingCore.BusinessEntities.Account, BankingCore"/>

 

where BankingCore.BusinessEntities.Account is the actual class to be instantiated for the property.

Monday, 24 August 2009

NHibernate HQL Query : could not resolve property

If you get

could not resolve property: ID: of

error for a HQL query and you know the property exists and is spelt correctly check that the query parameters are defined correctly.

Had this problem when query text was:

 

..... TaskStatus:=status ....

 

The problem is that the colon is the wrong side of the equals, should be

 

..... TaskStatus=:status ....

 

Error is easy typo to make but had to spot.

Thursday, 30 August 2007

Databind: Object does not match target type

This error sometimes occurs when trying to bind a result from a NHibernate query. It is caused by the first item in the list being a proxy value which causes the DataBind to use reflection of the proxy rather than the real target.

Details and solution taken from Alkampfer's Place.

Possible solution, requires object implements ICloneable:


public IList<T> SafeList<T>(IList<T> input) where T : class, ICloneable {
//Symply check the type of the first element.
if (input.Count > 0) input[0] = (T) input[0].Clone();
return input;
}



If object does not implement IClonable then need to turn off Lazy loading in mapping file.

Final Solution
As it was not pratical to make all objects ICloneable or to turn off lazy loading we finally settled on clearing the cache (Session.Clear) prior to executing queries or criterias.

Thursday, 7 June 2007

NHibernate:object references an unsaved transient instance

"object references an unsaved transient instance" recieved when performing a save (and transactional commit).
Caused by a related (parent) record not being saved and the entity not set up for cascading save.
e.g. User record has link to Person record but when user is saved the linked person is not saved.
Solution is either to turn on cascading saves for related entity or to explicity save the related record by creating a business object method.

Monday, 21 May 2007

NHibernate, GetType on Proxy

When lazy loading is true the returned type from a db call will be a proxy, so if you call GetType() you will get the proxy type not the underlying class.
To overcome this use NHibernateUtil.GetClass(object-instance).

Thursday, 5 April 2007

NHibernate:Unknown entity class:

Error "Unknown entity class: " occurs when either no mapping file exists for specifed or the mapping file is not flagged as embedded resource.

Monday, 26 March 2007

Nhibernate: Date time field null on insert

Receiving exception when trying to save a record the stack tarce identified theproblem as a null value for a DateTime field.
This is caused by either:
  1. Property not marked as nullable (? after Type in property declaration)
  2. Existing record being flushed that contains an invalid null value for datetime.

NHibernate: Object not set to instance on save

When saving I received 'Object not set to instance', from the stack trace the object in question was identified as the VerisionNo.
This was correctly defined for the table in question, after investigation it was identifeid as being a link table that was being flushed which had an existing record with a Null value for the VersionNo.
This record had been either manually entered or entered prior to the versionNo field being defined as NotNull.

Thursday, 8 March 2007

NHibernate Flush before Query

Was having a problem with following:
  1. Start Session
  2. Read object/record (presentation layer)
  3. Update record/object im memory (presentation layer)
  4. Run query to check changes valid (biz layer).
  5. If 4 ok commit changes inside transaction (biz layer)
  6. End session
Step 4 was identifying a problem and so steps 5 was not completed (i.e. no explicit Commit was called), the problem was that the record changes were still being written to the database.

This is caused by the FlushMode of the session be set to Auto. When set to auto NHibernate will sometimes flush the persistent obejct prior to performing a query.

There are a few solutions to this:
  • Perform updates to object after query (not applicable in this case due to layers)
  • Disconnect object prior to updating (Evict)
  • Change FlushMode to Commit
The solution decided upon was to change FlushMode to Commit and to also clear the session if a transaction fails and rollback is called.

Monday, 5 March 2007

How to map to a Generic IDictionary

Say you have a standard nHibernate Bag that maps to a IList

C# Definition

public virtual IList<UserGroup> Groups;


nHibernate Mapping

<bag name="UserGroups" table="UserGroup">
<key column="UserID"/>
<one-to-many class="UserGroup"/>
</bag>


You can change this to a IDictionary by changing the IList to a IDictionary in the Business Entity, then change the bag to a map,and adding a index setting to the nHibernate mapping.

So the above would be changed to

C# Definition

public virtual IDictionary<int,UserGroup> Groups;


nHibernate Mapping

<map name="UserGroups" table="UserGroup">
<key column="UserID"/>
<index column="GroupID" type="int"/>
<one-to-many class="UserGroup"/>
</map>


Where of course the index column is the column that you will search on, and the type is the type of the column.

NOTE - The Key Column and the Index column cannot be the same, but then thinking about that it would be pointless because the key value would be the same on all the keys of the dictionary.

NHibernate error loading class

Got the error:

Could not load type '...Page, SalecoreContent', check that type and assembly names are correct


Was caused by an incorrect class="Page" reference in one of the object mapping files.

Friday, 2 March 2007

nHibernate Get or Load?

Session.Get and Session.Load do very similar things, the difference is.

.Get will return null if a record is not found.
.Save will return an exception if a record is not found, and if it can use a proxy, it will return a proxy, so you won't get the exception until you try to actually use the object.

If you are not sure that a record exists then use .Get and check that the object isn't null.

NHibernate:How do I know a field is dirty?

The problem arose that I needed to know if a field had changed just prior to saving:

  1. Presentation layer reads object/record
  2. Presentation layer changes object field value
  3. Presentation layer calls business layer to update the object/record
  4. Business layer needs to know if a certain field has changed to perform extra processing
When the record is read (in step 4) from the database it actually comes from the (session) cache and therefore holds the values of the changed (but not yet persisted) fields.

The solution seems to be either clear the cache or tell the business object that the field has changed. The clear-the-cache solution was not tried, would have been along the lines of Session.Evict(object).

Tuesday, 27 February 2007

HQL Query - as, in errors

Tried to do a simple query:
from Page page

returned error ..expected in...

Tried
from Page as page

return error ..unexpected token:as..

After an hour of frustration realised that the object in C# was not called Page (I had renamed this to SalecorePage as it classed with the asp.net class:page).

The use of the wrong name stemmed from performing the query in SQL Server then porting to HQL.

Monday, 26 February 2007

NHibernate - Record re-read not showing server updates

Has an issue where re-reading a record the record did not include updates that had happened on the server:
1. Read USER record (e.g. Name=JOHN).
2. Update USER record on server (e.g. set Name=MIKE).
3. Read USER record again. Name is still JOHN.

This implied the record is being read from the cache.
The problem came down to the fact that the Data-access-object was being created as a Singleton which meant the Hibernate Session was not being opened and closed.
The record will only be re-read from the server outside of Session (i.e. Hibernate will read the record from the cache if inside the same session).

Solution was to change the Spring object mapping to not create the DAO as a singleton, this meant the session was being open/closed during page life cycle.

Thursday, 15 February 2007

NHibernate - a couple of transaction related issues

A couple of issues with transactional updates

1. Timeout expired.

A timeout expired error was occurring when attempting to update the same record (and field) twice within a single transaction.
This only occurred when the database update was being performed.
Solution: When updating a record multiple times do not perform the Update until all field values have been updated.

2. Illegal attempt to associate a collection with two open sessions
This error was returned when attempting to update child records of a parent record as well as updating the parent record, where the child record was being read independent of the parent record.
e.g
Parent record links to Child1 and Child2
Parent record read (which implicity reads Child1 & Child2 and puts in list Parent.Children)
Child1 record is read independently.
Parent record Updated.
Child1 record Updated.
There is no need to explicity read and update the Child1 instance. The instance (from Parent) should be updated (in memory) instead.

Wednesday, 14 February 2007

NHibernate save error.

Error: "object references an unsaved transient instance...."

This occurred when saving a object that had a 1:M relationship that was represented by a list.



Parent --- child1

--- child2



To fix the error add cascade="all" to the that represents the 1:M relationship in the DB Mapping file.