PDA

View Full Version : session management



acolmano
03-28-2007, 09:15 PM
Hi,
I try to configure NHibernate 1.2, Spring Preview 3 and NHibernate Module 12 to work together and I also need to make TransactionProxyFactoryObject.
The transaction interceptor configuration file is below:


<object id="TxProxyConfigurationTemplate" abstract="true" type="Spring.Transaction.Interceptor.TransactionProxyFac toryObject, Spring.Data">

<property name="PlatformTransactionManager" ref="HibernateTransactionManager"/>

<property name="TransactionAttributes">
<name-values>

<add key="*" value="PROPAGATION_REQUIRED"/>
<!--
<add key="Delete*" value="PROPAGATION_REQUIRED"/>
-->
</name-values>
</property>
<!-- defined in Aspects.xml -->
<property name="PreInterceptors" ref="CommonLoggingAroundAdvice"/>
</object>
<object id="CardServiceTx" parent="TxProxyConfigurationTemplate"> <property name="Target" ref="CardService"/>
</object>

........

<object id="SessionFactory" type="Spring.Data.NHibernate.LocalSessionFactoryObject, Spring.Data.NHibernate12">
<property name="DbProvider" ref="DbProvider"/>

<property name="MappingAssemblies">
<list>
<value>Abaco.Data</value>
</list>
</property>
<property name="HibernateProperties">
<dictionary>
<entry key="hibernate.connection.provider"
value="NHibernate.Connection.DriverConnectionProvider"/>

<entry key="hibernate.dialect"
value="NHibernate.Dialect.MsSql2000Dialect"/>

<entry key="hibernate.connection.driver_class"
value="NHibernate.Driver.SqlClientDriver"/>
</dictionary>
</property>
</object>

<object id="HibernateTransactionManager"
type="Spring.Data.NHibernate.HibernateTransactionManager , Spring.Data.NHibernate12">
<property name="DbProvider" ref="DbProvider"/>
<property name="SessionFactory" ref="SessionFactory"/>

</object>

I try to get a Dao object in first transactional method signed by [Transaction()] attribute.
In the second transaction I try to get the childs of previous object by its getters property. I received this exception:

NHibernate.LazyInitializationException: Could not initialize proxy - the owning Session was closed.

The hbm config file are below:
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" default-lazy="false">
<class name="Abaco.Dao.Domain.Contacts, Abaco.Dao" table="Contacts" lazy="true">
.........

<bag name="ContactDetails" cascade="all" inverse="true" generic="true" lazy="true" >
<key column="FK_Contact"/>
<one-to-many class="Abaco.Dao.Domain.ContactDetails, Abaco.Dao"/>
</bag>

........

Any idea? Any help would be great.

boriska
03-30-2007, 10:07 AM
Hello,

I would try to use another available alternative to handle transactions.
In my case I had used DeclarativeServicesAttributeDriven configuration and it worked for me.

I'm a Spring.Net novice myself, so I don't claim to have all the answers. But bellow you can see what I mean about your issue.

If you use OSIV then hibernate session' Flush mode will be set to FlushMode.Never in order to prevent data base operations until the http request will end.

Flush occurs only if you perform you service method within a transaction or explicitly call hibernate flush.

May be in your case after a transactional call on the Contact the ContactDetails get detached...

To make a long story short, in order to handle detached objects we can seize following chances (All was coined from a Spring\Hibernate book that I skimmed through yesterday):

Session per user session (hibernate-session will be saved in the http-session): "anti-pattern"

FetchType.Eager( in your case for ContactDetails)

Preemptive initializing, e.g. hibernate.initialize(Contact.ContactDetails)

Assosiate\Attach ContactDetails to Hibernate Session programmatically via LockMode.NONE

I hope these catchwords can give you a direction...

It would be great if the spring team would provide "how to" recipes or some docs to this subject! :)

Regards,
Boris

acolmano
03-31-2007, 11:54 AM
Thank you for your reply and your suggestion,
1) I was thinking that the FetchType.Eager would eliminate my problem, but I want to use Lazy initilization.
2) I can't use OpenSessionInView because I develop WinApp;
3) Hibernate.initialize(Contact.ContactDetails) does not initialize my object correctly
4) HibernateTemplate.Lock(....) don't reconnect my session

My application retrieve Contacts and ContactDetails in two different transactional method like that

[Transaction()]
public IList<Contacts> GetContacts()
{

return ContactsDao.GetAll();
}


[Transaction()]
public IList<ContactDetails> GetContactsDetails(Contacts ContactEntity)
{
IList<ContactsDetails> ContactsDetailsList = new List<ContactsDetails>();
return ContactsDetails.ContactDetails;
}


I' try to get childs through hibernate execute method and result was fine.
Any other idea???

boriska
03-31-2007, 04:04 PM
Hello,

probably you don't need [transaction] at all?!
I thought that you are building a web app...

I think if you don't perform write-operations to a db, you don't have to use a transaction proxy. It's only my suggestion however...


I read in spring.net forum something about transaction scope and a way how we can use the OSIV in winApp’s… Try to search for this topic!

Regards,
Boris

here a code sample of me ... CustomerService gets CustomerDAO injected by spring. May be you can organize your business logic in a simular way ...

[Transaction()]
public IList getOrdersByCustomerId(string customerID)
{

TransactionTemplate tt = new TransactionTemplate(TransactionManager);
IList result = (IList)tt.Execute(delegate
{
Customer customer = CustomerDAO.getCustomerById(customerID);
ArrayList al = new ArrayList();
foreach (Order order in customer.Orders)
{
al.Add(order);
}

return al;

});

return result;


}

steinard
04-01-2007, 12:20 AM
Hi!

I'm also making winapps and I use the Open Session in View module to control the life of the NHibernate session. Since the middleware we're building are to support remoting, com+ and webservices we decided to end the life of the session pr response.

Even extending the session's life for a usecase should now not be a problem since Erich Eichinger refactored the module not long ago. You can wrap it in a session scope guard as Erich suggested (http://forum.springframework.net/showthread.php?p=6285#post6285). I hope this was helpful.

Cheers,
Steinar.