-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 11 posts ] 
Author Message
 Post subject: Won't SQL Server 2005 Express return the identity (PK) value
PostPosted: Fri Jun 16, 2006 9:32 am 
Newbie

Joined: Fri Jun 16, 2006 9:19 am
Posts: 7
Hello everyone,

I'm new to NHibernate but have already gathered a lot of information and have built many apps with it. Upon changing the generator schema of one of my apps from assigned to identity (i let SQL Server 2005 auto-increment the primary key setting it to IsIdentity = true, Seed = 1, InitialValue = 1), i started to get the "this id generator generates Int64, Int32, Int16" exception. After further investigation, i found out that this was happening after the folowing CONVERT.CHANGETYPE in the method below, taken from IdentifierGeneratorFactory.cs file.

public static object Get( IDataReader rs, System.Type clazz )
{
// here is an interesting one:
// - MsSql's @@identity returns a Decimal
// - MySql LAST_IDENITY() returns an Int64
try
{
object identityValue = rs[ 0 ];
return Convert.ChangeType( identityValue, clazz ); <-- ERROR HERE
}
catch( Exception e )
{
throw new IdentifierGenerationException( "this id generator generates Int64, Int32, Int16", e );
}
}

The thing is: the object identityValue is empty. Thus, the conversion operation fails! It seens to me that SQL Server 2005 is not returning the PK value, am I wrong? Do you know what could i be doing wrong?!

I would really appreciate any help.

Hibernate version:
1.2.0.Alpha1-debug

Mapping documents:
Services.hbm.xml
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.0" assembly="DataObjectsLibrary1" namespace="DataObjectsLibrary1">
<class name="Service" table="Services">
<id name="PrimaryKey" column="PrimaryKey" unsaved-value="0">
<generator class="identity" />
</id>
<property name="Name" not-null="true" unique="true" />
<property name="Description" />
<property name="OperationMode" />
<property name="LearnMode" />
<property name="Lock" />
</class>
</hibernate-mapping>

Code between sessionFactory.openSession() and session.close():
Service Service1 = new Service();
Service1.Name = "SomeString";
Service1.Description = "SomeOtherString";

Session.Save(Service1);

Full stack trace of any exception that occurs:
at NHibernate.Id.IdentifierGeneratorFactory.Get(IDataReader rs, Type clazz) in c:\net\nhibernate\nhibernate\src\NHibernate\Id\IdentifierGeneratorFactory.cs:line 97
at NHibernate.Persister.Entity.AbstractEntityPersister.GetGeneratedIdentity(Object obj, ISessionImplementor session, IDataReader rs) in c:\net\nhibernate\nhibernate\src\NHibernate\Persister\Entity\AbstractEntityPersister.cs:line 1454
at NHibernate.Persister.Entity.AbstractEntityPersister.InsertImpl(Object[] fields, Boolean[] notNull, SqlString sql, Object obj, ISessionImplementor session) in c:\net\nhibernate\nhibernate\src\NHibernate\Persister\Entity\AbstractEntityPersister.cs:line 1811
at NHibernate.Persister.Entity.SingleTableEntityPersister.Insert(Object[] fields, Boolean[] notNull, SqlString sql, Object obj, ISessionImplementor session) in c:\net\nhibernate\nhibernate\src\NHibernate\Persister\Entity\SingleTableEntityPersister.cs:line 564
at NHibernate.Persister.Entity.SingleTableEntityPersister.Insert(Object[] fields, Object obj, ISessionImplementor session) in c:\net\nhibernate\nhibernate\src\NHibernate\Persister\Entity\SingleTableEntityPersister.cs:line 483
at NHibernate.Impl.ScheduledIdentityInsertion.Execute() in c:\net\nhibernate\nhibernate\src\NHibernate\Impl\ScheduledIdentityInsertion.cs:line 38
at NHibernate.Impl.SessionImpl.Execute(IExecutable executable) in c:\net\nhibernate\nhibernate\src\NHibernate\Impl\SessionImpl.cs:line 3163
at NHibernate.Impl.SessionImpl.DoSave(Object theObj, EntityKey key, IEntityPersister persister, Boolean replicate, Boolean useIdentityColumn, CascadingAction cascadeAction, Object anything) in c:\net\nhibernate\nhibernate\src\NHibernate\Impl\SessionImpl.cs:line 970
at NHibernate.Impl.SessionImpl.DoSave(Object obj, Object id, IEntityPersister persister, Boolean useIdentityColumn, CascadingAction cascadeAction, Object anything) in c:\net\nhibernate\nhibernate\src\NHibernate\Impl\SessionImpl.cs:line 882
at NHibernate.Impl.SessionImpl.SaveWithGeneratedIdentifier(Object obj, CascadingAction action, Object anything) in c:\net\nhibernate\nhibernate\src\NHibernate\Impl\SessionImpl.cs:line 777
at NHibernate.Impl.SessionImpl.Save(Object obj) in c:\net\nhibernate\nhibernate\src\NHibernate\Impl\SessionImpl.cs:line 718
at ConsoleApplication1.Program.Test1() in C:\Documents and Settings\cmendonca\My Documents\Visual Studio 2005\Projects\Simulator5\ConsoleApplication1\Program.cs:line 43
at ConsoleApplication1.Program.Main(String[] args) in C:\Documents and Settings\cmendonca\My Documents\Visual Studio 2005\Projects\Simulator5\ConsoleApplication1\Program.cs:line 16
at System.AppDomain.nExecuteAssembly(Assembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()

Name and version of the database you are using:
SQL Server 2005 Express (9.0)

Carlos


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jun 21, 2006 3:16 am 
Regular
Regular

Joined: Fri Feb 18, 2005 3:34 am
Posts: 88
Location: Poland/Wrocław
It would really help, if I saw the whole exception, especially its type...

_________________
Please rate this post if you've found it helpfull
Roland


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jun 21, 2006 9:51 am 
Newbie

Joined: Fri Jun 16, 2006 9:19 am
Posts: 7
Well... I will only have access to the application on Friday so, I can't really post any other details right now.

Regarding the exception type, as we take a look at the code from NHibernate's Get() method I posted above, one can see that it is an IdentifierGenerationException. But I'm not sure if that helps.

As I said: upon debuging the program, I realised that the identityValue that should come from IDataReader rs is blank. Thus, Convert.ChangeType fails.

If anyone could post a *very* simple step-by-step procedure of how to configure a system with a single class mapped to a SQL 2K5 table with automatically-incremented PrimaryKey and some other field, I could try to run it and test if it is a SQL 2K5 problem or not. (It's probably a misconfiguration or something I'm doing wrong).

So, in other words, what we would need to test is:

1) simple class:

class User
{
private int _PrimaryKey;
private string _Username;

public virtual string Username
{
get { return this._Username; }
set { this._Username = value; }
}

public User()
: this(string.Empty)
{
}
public User(string Username)
{
this._PrimaryKey = 0;
this._Username = Username;
}
}

2) simple SQL 2K5 database:

column 1: PrimaryKey, integer, IsIdentity = true (i.e. with auto-increment)
column 2: Username, varchar(50)

3) config file + User.hbm.xml (making sure that the ID tag sets generator="identity")

4) helper class to test:

(..)
Session.Save(new User("SomeUserName"));
(..)

So... is anyone up to do that test and send me the package if it is sucessful? I would really appreciate any help.

Yours,

Carlos


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jun 21, 2006 12:56 pm 
Pro
Pro

Joined: Fri Nov 19, 2004 5:52 pm
Posts: 232
Location: Chicago, IL
If this is a new app, I would recommend generating your database schema using SchemaExport. This way you know all the data types in the database match up with what you have defined in your data model/mapping files.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jun 22, 2006 9:49 pm 
Newbie

Joined: Fri Jun 16, 2006 9:19 am
Posts: 7
Hey everyone... i guess i've finally solved the problem. I am not really sure of what was the glitch, but i think it was related to the way i was creating my mapping files. Anyway, one thing one can notice that is really differente is the way i declare the .NET types. I will post mapping files after and before so they can speak for themselves. I would really like to thank those above who helped.

THIS WORKS:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.0">
<class name="WebServices.Simulator.Data.Service, DataLayerLibrary1" table="Services" lazy="true">
<id name="PrimaryKey" column="PrimaryKey" type="System.Int32" unsaved-value="0">
<generator class="identity"/>
</id>
<property column="Name" type="System.String" name="Name" />
<property column="Description" type="System.String" name="Description" />
<property column="IsSimulationMode" type="System.Boolean" name="IsSimulationMode" />
<property column="IsLearnMode" type="System.Boolean" name="IsLearnMode" />
<property column="IsLocked" type="System.Boolean" name="IsLocked" />
<set name="SoapInputs" inverse="true" cascade="all-delete-orphan">
<key column="ServicesForeignKey" />
<one-to-many class="WebServices.Simulator.Data.SoapInput, DataLayerLibrary1" />
</set>
</class>
</hibernate-mapping>

INSTEAD OF THIS:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.0" assembly="DataLibrary1" namespace="DataLibrary1">
<class name="Service" table="Services">
<id name="PrimaryKey" column="PrimaryKey" type="Int32" unsaved-value="0">
<generator class="native" />
</id>
<property name="Name" not-null="true" unique="true" />
<property name="Description" />
<property name="OperationMode" />
<property name="LearnMode" />
<property name="Lock" />
<set name="SoapInputs" inverse="true" cascade="all-delete-orphan">
<key column="ServicesForeignKey" />
<one-to-many class="SoapInput"/>
</set>
</class>
</hibernate-mapping>

Carlos


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jun 23, 2006 4:09 am 
Regular
Regular

Joined: Fri Feb 18, 2005 3:34 am
Posts: 88
Location: Poland/Wrocław
chemendonca wrote:

THIS WORKS:

<id name="PrimaryKey" column="PrimaryKey" type="System.Int32" unsaved-value="0">
<generator class="identity"/>
</id>

INSTEAD OF THIS:

<id name="PrimaryKey" column="PrimaryKey" type="Int32" unsaved-value="0">
<generator class="native" />
</id>


In my opinion the problem was exactly with the ID generator. However in your primary post you.ve presented ``identity'' which is a propper...

Anyway, in the ``native'' you are responsible to set the value. Thus you did not have it after saving when did not set it up previosly.

_________________
Please rate this post if you've found it helpfull
Roland


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jun 23, 2006 6:43 am 
Expert
Expert

Joined: Thu Jan 19, 2006 4:29 pm
Posts: 348
rolandz wrote:
Anyway, in the ``native'' you are responsible to set the value. Thus you did not have it after saving when did not set it up previosly.


'native' should pick the genartor native to the database backend. In case of MS SQL server, it should be equal to 'identity'.

And 'assigned' is the generator where You are responsible for assigning value.

Gert

_________________
If a reply helps You, rate it!


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jun 23, 2006 7:34 am 
Regular
Regular

Joined: Fri Feb 18, 2005 3:34 am
Posts: 88
Location: Poland/Wrocław
gert wrote:
'native' should pick the genartor native to the database backend. In case of MS SQL server, it should be equal to 'identity'.

And 'assigned' is the generator where You are responsible for assigning value.


Yes, you're completely right... I'm sorry for confusing - made a mistake.

However, what couold be a problem that has been descibed in this thread? I don't understand it now and I wish I did.

_________________
Please rate this post if you've found it helpfull
Roland


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jun 23, 2006 9:01 am 
Expert
Expert

Joined: Thu Jan 19, 2006 4:29 pm
Posts: 348
rolandz wrote:
However, what couold be a problem that has been descibed in this thread? I don't understand it now and I wish I did.


Maybe NHibernate thinks for some reason that native should mean something other than identity? Like incorrect dialect or driver used or something?

Gert

_________________
If a reply helps You, rate it!


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jun 23, 2006 2:02 pm 
Regular
Regular

Joined: Wed Jun 21, 2006 3:13 pm
Posts: 110
Carlos,

Can you post your dialect info from your config file?

Also, you changed two things in the mappings, right? Both the type for the ID (qualifying it to the System namespace) and the switch to identity.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jun 23, 2006 9:37 pm 
Newbie

Joined: Fri Jun 16, 2006 9:19 am
Posts: 7
benhyrman wrote:
Carlos,

Can you post your dialect info from your config file?

Also, you changed two things in the mappings, right? Both the type for the ID (qualifying it to the System namespace) and the switch to identity.


benhyrman,

no, actually i had tried both generator="identity" and generator="native". But yes, one important change was the introduction of the System namespace which i think is what solved the problem.

Also, you can see that although the column names in the DB and the field names in the classes are the same, i'm specifiying each one of them in the mapping files. Documentation says it is not necessary, but i decided to follow the pattern from MyGeneration.

The dialect i'm using is MsSql2005Dialect... but the results were the same if i used MsSql2000Dialect.

I didn't change anything in the configuration file. The nhibernate.cfg.xml is the following (just in case anyone is curious):

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.0">
<session-factory>
<property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property>
<property name="connection.driver_class">NHibernate.Driver.SqlClientDriver</property>
<property name="connection.connection_string">Data Source=COMPUTADOR-2\SQLEXPRESS;Initial Catalog=Scopus1;Integrated Security=True</property>
<property name="dialect">NHibernate.Dialect.MsSql2005Dialect</property>
<property name="connetion.isolation">ReadCommited</property>
<property name="default_schema">Scopus1.dbo</property>

<mapping assembly="DataLayerLibrary1"/>
</session-factory>

</hibernate-configuration>

Thanks again for the feedback,

Carlos


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 11 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
cron
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.