View Full Version : What is the best way to configure the HibernateTemplate
blega
12-13-2006, 02:46 PM
Hello,
HibernateTemplate happens to need some configuration :
for example, the AdoExceptionTranslator has to be set.
Otherwise, when an error occurs in Spring.Data.Nhibernate,
the code fails to report it because a NullReferenceException
breaks in (AdoExceptionTranslator not set).
I was wondering where is the best place to configure the AdoTranslator ?
Solution 1 : in the spring configuration for the class using the
HibernateTemplate ?
Using the standard property compound feature, I could write
<object id="AdoExceptionTranslator"
type="Spring.Data.Support.ErrorCodeExceptionTranslator, Spring.Data" >
<constructor-arg name="provider" ref="DbProvider"/>
</object>
<object id="EtablissementDao"
type="Rra.ExploraSup.Domain.NHibernateImpl.Dao.Etablisse mentDao, Rra.ExploraSup.Domain.NHibernateImpl">
<property name="SessionFactory" ref="SessionFactory"/>
<property name="HibernateTemplate.AdoExceptionTranslator" ref="AdoExceptionTranslator"/>
</object>
Solution 2 : is there one ? Is there a place where
the default spring wiring for the HibernateTemplate is done ?
Should one be created ?
Thanks for your feedback,
Bertrand.
blega
12-13-2006, 03:15 PM
Trying to implement solution 1, I get the following exception :
"'ErrorCode' node cannot be resolved for the specified root context."
Spring.Expressions.PropertyOrFieldNode.InitializeN ode(Object context)
Spring.Expressions.PropertyOrFieldNode.Get(Object context, IDictionary variables)
Spring.Expressions.BaseNode.GetValue(Object context, IDictionary variables)
Spring.Expressions.Expression.Get(Object context, IDictionary variables)
Spring.Expressions.BaseNode.GetValue(Object context, IDictionary variables)
Spring.Expressions.ExpressionEvaluator.GetValue(Ob ject root, String expression)
Spring.Data.Common.DbProvider.ExtractError(Excepti on e)
Spring.Data.Support.ErrorCodeExceptionTranslator.E xtractErrorCode(Exception exception)
Spring.Data.Support.ErrorCodeExceptionTranslator.T ranslate(String task, String sql, Exception exception)
Spring.Data.NHibernate.HibernateAccessor.ConvertAd oAccessException(ADOException ex)
Spring.Data.NHibernate.HibernateAccessor.ConvertHi bernateAccessException(HibernateException ex)
Spring.Data.NHibernate.HibernateTemplate.Execute(I HibernateCallback action, Boolean exposeNativeSession)
Spring.Data.NHibernate.HibernateTemplate.LoadAll(T ype entityType)
Rra.ExploraSup.Domain.NHibernateImpl.Dao.Base.Etab lissementDaoBase.FindAll()
Rra.ExploraSup.Services.Impl.EtablissementService. FindAllEtablissements()
Rra.ExploraSup.Website.Test.Page_Load(Object sender, EventArgs e)
System.Web.Util.CalliHelper.EventArgFunctionCaller (IntPtr fp, Object o, Object t, EventArgs e)
System.Web.Util.CalliEventHandlerDelegateProxy.Cal lback(Object sender, EventArgs e)
System.Web.UI.Control.OnLoad(EventArgs e)
System.Web.UI.Control.LoadRecursive()
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
Surprisingly, in the ErrorCodes property I get all the error codes defined in my DbProvider (via DbProvider.xml).
Am I doing something wrong ?
Mark Pollack
12-13-2006, 04:02 PM
Hi,
You should not have to set the translator explicitly. The get property will set it to ErrorCodeExceptionTranslator if a DbProvider is matched to the SessionFactory, otherwise FallbackExceptionTranslator is used. Null should never be returned, if so it is a bug. You work around should have worked in anycase, which makes me wonder what DB and version of Spring.Data.Hibernate are you using?
I am in the process right now of updating the Spring.Net.Integration area to use the latest release (slightly modified as I forgot to add the exceptions that were in Spring.Data.Orm to Spring.Data). This should be done in a few hours, at that time you can download a new version and give it a try. I will add unit tests to check for this behavior, unit tests are the major goal before making a preview release.
Thanks for reporting this.
Mark
blega
12-13-2006, 04:43 PM
Thanks for your feedback.
I'll give a try tomorrow,
Bertrand.
Mark Pollack
12-13-2006, 08:18 PM
Hi Bertrand,
OK, your issue should be resolved now. Pick up the "1213-1510" dated .zip file from the download page (http://www.springframework.net/downloads/Spring.Data.NHibernate/) and let me know if you still have any issues.
Cheers,
Mark
blega
12-15-2006, 02:37 PM
Hello,
I got the files from the nightly build you recommended.
AdoExceptionTranslator is not null anymore, but I'm
afraid the error translation still doesn't work for me.
AdoExceptionTranslator is set to {Spring.Data.Support.FallbackExceptionTranslator}.
And then, in the call to the Translate method, a null reference exception
occurs.
But the problem is that the Spring modules shipped with
the Spring.Data.Nhibernate does not have the debug info
(ie the pdb) so I can't step into the code to see
where the error lies.
Could it be possible to have the pdb embedded in the
nightly build of Spring.Data.Nhibernate ?
By the way, how I could build a release of Spring+Spring.Data.Nhibernate ?
Which module should I take : Spring.Net or Spring.Net.Integration ?
Mark Pollack
12-15-2006, 03:42 PM
Hi,
Hmmm, if FallbackExceptionTranslator is being returned it means that the call to SessionFactoryUtils.GetDbProvider did not return a matching Spring IDbProvider from the SessionFactory. That is the crux of the problem at the moment. Which IDbProvider are you using?
I've removed the attempt in FallbackExceptionTranslator to convert the exception. That is a flat out bug. FallbackExceptionTranslator now always throws an UncategorizedAdoException, as intended.
I will package the .pdb and post back here when it is available on the download page.
If you want to build Spring + Spring.NH, you should get the daily download for Spring, recompile with the vs.net solution, copy the Spring .dlls to the lib directory in the Spring.NH daily download, then rebuild Spring.NH with the vs.net solution. Alternatively, you can remove the refs to the .dlls in the current Spring.NH project and include the various .csproj files from Spring. I am working on having the integration projects use latest spring .dlls builds.
Hope this helps and thanks for reporting these issues.
Mark
blega
12-18-2006, 10:29 AM
I did the test with the following IDbPorvider :
- Oracle provider="OracleODP-2.0" . And I get the error described in my previous posts
- MySql provider="MySql", AdoTranslator :ErrorCodeExceptionTranslator
A first chance exception of type 'Spring.Objects.InvalidPropertyException' occurred in Spring.Core.DLL
Additional information: 'Number' node cannot be resolved for the specified root context.
The MySql error seems to have an unexpected exception type.
I attached a screenshot which show the exception stack
To reproduce the error, I simply mess up with the connection
settings of the database.
The error doesn't occur with a regular database error (integrity, etc.).
I'll make a try with the new dll/pdb.
Thanks for your help,
B.
Mark Pollack
12-23-2006, 09:42 PM
Hi,
I've tried to reproduce the error with AdoTemplate code with OracleODP-2.0 and got an exception which I forgot to wrap in one of Spring's DAO exceptions. I fixed this and ConnectionUtils.GetConnectionTxPair now throws CannotGetAdoConnectionException, though I'm not sure this is related to your problem, i.e.
'ErrorCode' node cannot be resolved for the specified root context."
Hopefully it will obvious once I have a NH example going with Oracle. It is strange because I know that for oracle the exception translation works fine in AdoTemplat based code that people use on current projects.
Anyway, the NHibernate daily build process now uses the latest daily builds available of Spring.Core/Data etc, and the .pdb are included. If you want to get an updated distribution yourself you can trigger it from the cruise control (http://ciweb.codestreet.com:88/ccnet/default.aspx?_action_ViewFarmReport=true)page.
I'll setup a NHibernate example with Oracle next to see if I can reproduce you case. Sorry for the delay. I hope the current download (http://www.springframework.net/downloads/Spring.Data.NHibernate/)will provide you enough info to futher debug.
Mark
Mark Pollack
01-01-2007, 10:07 PM
Hi,
I setup an NHibernate example with Oracle and did not get the error you reported. In my test case I created a simple object via NH (1.0.2) in Oracle and then changed the connection string to have bad password (also tried bad Data Source). I got the following exception which is ok.
Spring.Transaction.CannotCreateTransactionExceptio n: Could not open Hibernate Session for transaction
at Spring.Data.NHibernate.HibernateTransactionManager .DoBegin(Object transaction, ITransactionDefinition definition) in HibernateTransactionManager.cs:line 403
at Spring.Transaction.Support.AbstractPlatformTransac tionManager.GetTransaction(ITransactionDefinition definition)
at Spring.Transaction.Interceptor.TransactionAspectSu pport.CreateTransactionIfNecessary(MethodInfo method, Type targetType)
at Spring.Transaction.Interceptor.TransactionIntercep tor.Invoke(IMethodInvocation invocation)
at Spring.Aop.Framework.AbstractMethodInvocation.Proc eed()
at Spring.Aop.Framework.DynamicProxy.AdvisedProxy.Inv oke(Object proxy, Object target, Type targetType, MethodInfo targetMethod, Object[] args, IList interceptors)
at Spring.Proxy.CompositionAopProxy_83be24d7aa9144219 210d0f8c5797164.Create(TestObject to)
at Spring.Data.NHibernate.TemplateTests.DemoDao() in TemplateTests.cs:line 118
NHibernate.ADOException: cannot open connection
at NHibernate.Impl.SessionFactoryImpl.OpenConnection( )
at NHibernate.Impl.SessionImpl.get_Connection()
at Spring.Data.NHibernate.HibernateTransactionManager .DoBegin(Object transaction, ITransactionDefinition definition) in HibernateTransactionManager.cs:line 341
NHibernate.ADOException: Could not create connection from Driver
at NHibernate.Connection.DriverConnectionProvider.Get Connection()
at NHibernate.Impl.SessionFactoryImpl.OpenConnection( )
System.Data.OracleClient.OracleException: ORA-01017: invalid username/password; logon denied
at System.Data.OracleClient.OracleException.Check(Oci ErrorHandle errorHandle, Int32 rc)
at System.Data.OracleClient.OracleInternalConnection. OpenOnLocalTransaction(String userName, String password, String serverName, Boolean integratedSecurity, Boolean unicode, Boolean omitOracleConnectionName)
at System.Data.OracleClient.OracleInternalConnection. .ctor(OracleConnectionString connectionOptions)
at System.Data.OracleClient.OracleConnectionFactory.C reateConnection(DbConnectionOptions options, Object poolGroupProviderInfo, DbConnectionPool pool, DbConnection owningObject)
at System.Data.ProviderBase.DbConnectionFactory.Creat ePooledConnection(DbConnection owningConnection, DbConnectionPool pool, DbConnectionOptions options)
at System.Data.ProviderBase.DbConnectionPool.CreateOb ject(DbConnection owningObject)
at System.Data.ProviderBase.DbConnectionPool.UserCrea teRequest(DbConnection owningObject)
at System.Data.ProviderBase.DbConnectionPool.GetConne ction(DbConnection owningObject)
at System.Data.ProviderBase.DbConnectionFactory.GetCo nnection(DbConnection owningConnection)
at System.Data.ProviderBase.DbConnectionClosed.OpenCo nnection(DbConnection outerConnection, DbConnectionFactory connectionFactory)
at System.Data.OracleClient.OracleConnection.Open()
at NHibernate.Connection.DriverConnectionProvider.Get Connection()
Here is the configuration file I used to set this up, taken from the 'integration' test project in the NH solution.
<objects xmlns='http://www.springframework.net'
xmlns:db="http://www.springframework.net/database">
<db:dbProvider id="DbProvider"
provider="OracleODP-2.0"
connectionString="Data Source=AGORA; User Id=agora_user; Password=welcome_bad"/>
<object id="SessionFactory" type="Spring.Data.NHibernate.LocalSessionFactoryObject, Spring.Data.NHibernate">
<!-- TODO Provide dedicated NHibernate Schema -->
<property name="DbProvider" ref="DbProvider"/>
<property name="MappingResources">
<list>
<value>assembly://Spring.Data.NHibernate.Integration.Tests/Spring.Data.NHibernate/TestObject.hbm.xml</value>
</list>
</property>
<property name="HibernateProperties">
<dictionary>
<entry key="hibernate.connection.provider"
value="NHibernate.Connection.DriverConnectionProvider"/>
<entry key="hibernate.dialect"
value="NHibernate.Dialect.Oracle9Dialect"/>
</dictionary>
</property>
</object>
<object id="NHTestObjectDao" type="Spring.Data.NHibernate.NHTestObjectDao, Spring.Data.NHibernate.Integration.Tests">
<property name="SessionFactory" ref="SessionFactory"/>
</object>
<!-- Transactional Proxy for TestObjectManager using the ProxyFactoryObject -->
<object id="testObjectDaoViaTxAttributes"
type="Spring.Aop.Framework.ProxyFactoryObject, Spring.Aop">
<property name="Target" ref="NHTestObjectDao"/>
<property name="InterceptorNames">
<value>transactionInterceptor</value>
</property>
</object>
<object id="hibernateTransactionManager"
type="Spring.Data.NHibernate.HibernateTransactionManager , Spring.Data.NHibernate">
<property name="DbProvider" ref="DbProvider"/>
<property name="sessionFactory" ref="SessionFactory"/>
</object>
<!-- Transaction Interceptor based on attribute [Transaction()] -->
<object id="transactionInterceptor"
type="Spring.Transaction.Interceptor.TransactionIntercep tor, Spring.Data">
<property name="TransactionManager" ref="hibernateTransactionManager"/>
<!-- note do not have converter from string to this property type registered -->
<property name="TransactionAttributeSource">
<object type="Spring.Transaction.Interceptor.AttributesTransacti onAttributeSource, Spring.Data"/>
</property>
</object>
</objects>
I just added support for specifying IResource locations for NHibernate mapping files, this is the MappingResources property above. If you can post your configuration and tell me which download dated version of Spring-NH you are using that would help.
Mark
Powered by vBulletin® Version 4.1.5 Copyright © 2012 vBulletin Solutions, Inc. All rights reserved.