View Full Version : Configuring Spring with NHibernate and Interceptors
fernaramburu
10-18-2006, 05:16 PM
Hi,
I´ve been reading Spring documentation and Spring forums but I can´t find an answer for my doubt
I want to configure NHibernate to work with Spring and I also need to make a proxy so I can put some interceptors (log and business interceptors). I try to configure a TransactionProxyFactoryObject but I can´t make interceptors to work there.
I also want Transactions to be transparent for programmers so I don´t want Transaction Attribute to be indicating where in my code transactions start or appear. I don´t like to much attributes like this because they give responsability to the programmer to make the code work.
I had try some possibilities but I can´t make that work. I also tried with ProxyFactoryObject as in the Spring-NHibernate integration tests but I can´t make it work with Transaction Interceptors
Any idea? Any help would be great.
thanks in advance.
Fernando Arámburu
Mark Pollack
10-18-2006, 09:17 PM
Hi Fernando,
I've updated the sample application located under
Spring.Net.Integration\projects\Spring.Data.NHiber nate\examples\Spring\Spring.Northwind
in CVS to show you how to do this. I've structured the project in what I consider to be a fairly real-world manner though it is clearly overkill for such a simple project.
The key bit of configuration to do what you want is located in the file DeclarativeServicesTxProxyFactoryDriven.xml
<object id="TxProxyConfigurationTemplate" abstract="true"
type="Spring.Transaction.Interceptor.TransactionProxyFac toryObject, Spring.Data">
<property name="PlatformTransactionManager"ref="HibernateTransactionManager"/>
<property name="TransactionAttributes">
<name-values>
<!-- Add common methods across your services here -->
<add key="Process*"value="PROPAGATION_REQUIRED"/>
<!--
<add key="Delete*" value="PROPAGATION_REQUIRED"/>
-->
</name-values>
</property>
<!-- note you can use alias names so that this configuration file is -->
<!-- not dependent on the precise object name of the logging advice -->
<!-- defined in Aspects.xml -->
<property name="PreInterceptors" ref="Log4NetLoggingAroundAdvice"/>
</object>
<object id="FulfillmentServiceUsingTxPFO" parent="TxProxyConfigurationTemplate">
<!-- Note: would likely use an anonymous inner object instead of a reference -->
<!-- to ensure that no one can access an unadvised object -->
<property name="Target" ref="FulfillmentService"/>
</object>
When you go with the approach of using TransactionProxyFactoryObject it helps after a while to factor out the common configuration into an abstract parent object. You can read more about this approach on Colin's blog (http://blog.exis.com/colin/archives/2004/07/31/concise-transaction-definitions-spring-11/).
The PreInterceptors lets you put AOP interceptor advice before the transaction advice. There is also a corresponding PostInterceptors property.
By changing which version of the DelcarativeServicesXXX.xml file included in Services.xml you can select among various declarative transaction demarcation options.
I've written the example so far as a test, so you will need to either run this via NUnit in your IDE or do a little reworking to make it a console application.
Let me know if you have any issues getting at this via cvs.
Cheers,
Mark
fernaramburu
10-19-2006, 02:23 PM
Mark,
Thanks for your very complete answer. I will see it today and I hope I can make it work on my project.
Thanks
Fernando Arámburu
fernaramburu
10-19-2006, 06:53 PM
Mark,
My example did work with your help. Thank you very much.
Anyway, i´m having another problem. I don´t understand DbProviders specially because I´m having an error there because my NHibernate will interact with a MySQL Database and I don´t get the idea why Spring must worry about how, why and where NHibernate interact with a concrete Database.
I´ve already found on a Jira SPRNET-348 (http://opensource.atlassian.com/projects/spring/browse/SPRNET-348) that implements a Provider but I know will have problems soon because i´ve also need to interact with a Sybase DB.
Thanks for all, and hope I can help somehow to this excellent project.:-D
Fer
Mark Pollack
10-20-2006, 10:19 PM
Hi,
I'm right in the middle of cleaning up the way DbProviders are specified so that many databases will be supported out of the box. The reason right now that the NHibernate support is aware of the spring-like mechanism for dbproviders is so that we can support mixed ADO.NET based operations (via AdoTemplate) with hibernate operations within the same transaction. Spring's 'DbProvider' would be the common ground. Another user did a bunch of hacking to get it all to work w/out specifying that - in anycase I gotta clean that up because the typical scenario isn't to mix ado.net/nhibernate operations. Let me look at it this weekend.
Cheers,
Mark
fernaramburu
10-21-2006, 01:14 AM
Mark,
Just tell me if I can give you any kind of help.
I will be really happy if I can help you and Spring.NET
Fer
Mark Pollack
10-22-2006, 06:08 AM
Hiya,
I've updated the DbProvider implementation, the docs are here (http://www.springframework.net/doc-latest/reference/html/dbprovider.html). If you grok through the file dbproviders.xml you should be able to write your own for sybase. If you do, please post it here. You'll need to get the latest code from cvs, the daily builds are not working - something is seriously wrong with the machine and I have to investiate.
Cheers,
Mark
Tommy_Shen
11-14-2006, 06:01 AM
Hi,
sorry for my poor english!
here is the another problem with me. when i tried to use the TransactionProxyFactoryObject as my transaction service base, i got a TypeCastException:
my configuration:
<object id="BaseTxService" abstract="true"
type="Spring.Transaction.Interceptor.TransactionProxyFac toryObject, Spring.Data">
<property name="PlatformTransactionManager" ref="HibernateTransactionManager"/>
<property name="TransactionAttributes">
<name-values>
<add key="Save*" value="PROPAGATION_REQUIRED"/>
<add key="Remove*" value="PROPAGATION_REQUIRED"/>
</name-values>
</property>
</object>
<object id="MemberManager" parent="BaseTxService">
<property name="Target">
<object type="DDA.GA.Business.MemberManager, DDA.GA.Business"/>
</property>
</object>
my code:
[SetUp]
public void Init()
{
ctx = ContextRegistry.GetContext();
object obj = ctx["MemberManager"];
if (obj != null)
{
Console.WriteLine(obj.ToString());
memberManager = obj as MemberManager;
if (memberManager != null)
{
Console.WriteLine("OK!");
}
else
{
Console.WriteLine("Error!{0},{1}", obj.GetType().Namespace, obj.GetType().Name);
}
}
//memberManager = (MemberManager) ctx.GetObject("memberManager");
}
when i run this test, i always get the ouput like "Error!Spring.Proxy,CompositionAopProxy_49240ab6f28 f402bb3801cbe4324d730"
could anyone help me? thanks.
Tommy_Shen
11-14-2006, 10:10 AM
here is my example code, and it also appear the error about declarative transaction.
tbroyer
11-14-2006, 11:00 AM
here is the another problem with me. when i tried to use the TransactionProxyFactoryObject as my transaction service base, i got a TypeCastException
[...]
memberManager = (MemberManager) ctx.GetObject("memberManager");
Others will correct me if I'm wrong, but proxy objects do not inherit from your class, they "just" implement interfaces. So you must use an interface, have MemberManager implement that interface, and cast to the interface, not the class.
Didn't they chang the proxy stuff from composition to inheritance ?
*edit:*
http://forum.springframework.net/showthread.php?t=260
Tommy_Shen
11-14-2006, 01:41 PM
thanks for all reply, i solve this issue at once. but another question:
does the interface support Generic declare? like :
public interfact IBaseManager<T>
{
void Save(T entity);
void Remove(object id);
void Remove(T entity);
}
it seems not support in current version, or must i make mistakes?
Bruno Baia
11-14-2006, 11:22 PM
Hi all,
About proxying classes :
Both composition and decorator based proxy are implemented in current dev (latest official 1.0.2 does not support it).
So you can proxy a class that does not implement any interfaces. What you need to know is that only virtual methods are proxied.
In this case you will be able to cast your object into your type.
About generics support in proxies :
This have been resolved recently (http://forum.springframework.net/showthread.php?t=644).
which version are you using ?
Bruno
Bruno Baia
11-15-2006, 11:06 PM
Hi,
I've committed a fix.
It will be available in the next nightly build.
More information in this post (http://forum.springframework.net/showthread.php?p=3766#post3766).
Bruno
Powered by vBulletin® Version 4.1.5 Copyright © 2012 vBulletin Solutions, Inc. All rights reserved.