diff --git a/doc/reference/src/orm.xml b/doc/reference/src/orm.xml
index 3c82044f..c3f3ab82 100644
--- a/doc/reference/src/orm.xml
+++ b/doc/reference/src/orm.xml
@@ -394,158 +394,31 @@
instances based on values in thread local storage, much like the
implementation of MultiDelegatingDbProvider.
-
-
- The HibernateTemplate
+
+ Spring's IByteCodeProvider implementation
- The basic programming model for templating looks as follows for
- methods that can be part of any custom data access object or business
- service. There are no restrictions on the implementation of the
- surrounding object at all, it just needs to provide a Hibernate
- SessionFactory. It can get the latter from anywhere,
- but preferably as an object reference from a Spring IoC container - via
- a simple SessionFactory property setter. The
- following snippets show a DAO definition in a Spring container,
- referencing the above defined SessionFactory, and an
- example for a DAO method implementation.
-
- <objects>
-
- <object id="CustomerDao" type="Spring.Northwind.Dao.NHibernate.HibernateCustomerDao, Spring.Northwind.Dao.NHibernate">
- <property name="SessionFactory" ref="MySessionFactory"/>
- </object>
-
-</objects>
-
-
-
- public class HibernateCustomerDao : ICustomerDao {
-
- private HibernateTemplate hibernateTemplate;
-
- public ISessionFactory SessionFactory
- {
- set { hibernateTemplate = new HibernateTemplate(value); }
- }
-
- public Customer SaveOrUpdate(Customer customer)
- {
- hibernateTemplate.SaveOrUpdate(customer);
- return customer;
- }
-}
-
- The HibernateTemplate class provides many
- methods that mirror the methods exposed on the Hibernate
- Session interface, in addition to a number of
- convenience methods such as the one shown above. If you need access to
- the Session to invoke methods that are not exposed on
- the HibernateTemplate, you can always drop down to a
- callback-based approach like so.
-
- public class HibernateCustomerDao : ICustomerDao {
-
- private HibernateTemplate hibernateTemplate;
-
- public ISessionFactory SessionFactory
- {
- set { hibernateTemplate = new HibernateTemplate(value); }
- }
-
- public Customer SaveOrUpdate(Customer customer)
- {
- return HibernateTemplate.Execute(
- delegate(ISession session)
- {
- // do whatever you want with the session....
- session.SaveOrUpdate(customer);
- return customer;
- }) as Customer;
- }
-
-}
-
- Using the anonymous delegate is particularly convenient when you
- would otherwise be passing various method parameter calls to the
- interface based version of this callback. Furthermore, when using
- generics, you can avoid the typecast and write code like the
- following
-
- IList<Supplier> suppliers = HibernateTemplate.ExecuteFind<Supplier>(
- delegate(ISession session)
- {
- return session.CreateQuery("from Supplier s were s.Code = ?")
- .SetParameter(0, code)
- .List<Supplier>();
- });
-
- where code is a variable in the surrounding block, accessible
- inside the anonymous delegate implementation.
-
- A callback implementation effectively can be used for any
- Hibernate data access. HibernateTemplate will ensure
- that Session instances are properly opened and
- closed, and automatically participate in transactions. The template
- instances are thread-safe and reusable, they can thus be kept as
- instance variables of the surrounding class. For simple single step
- actions like a single Find, Load, SaveOrUpdate, or Delete call,
- HibernateTemplate offers alternative convenience
- methods that can replace such one line callback implementations.
- Furthermore, Spring provides a convenient
- HibernateDaoSupport base class that provides a
- SessionFactory property for receiving a
- SessionFactory and for use by subclasses. In
- combination, this allows for very simple DAO implementations for typical
- requirements:
-
- public class HibernateCustomerDao : HibernateDaoSupport, ICustomerDao
-{
- public Customer SaveOrUpdate(Customer customer)
- {
- HibernateTemplate.SaveOrUpdate(customer);
- return customer;
- }
-}
-
-
-
- Implementing Spring-based DAOs without callbacks
-
- As an alternative to using Spring's
- HibernateTemplate to implement DAOs, data access code
- can also be written in a more traditional fashion, without wrapping the
- Hibernate access code in a callback, while still respecting and
- participating in Spring's generic DataAccessException
- hierarchy. The HibernateDaoSupport base class offers
- methods to access the current transactional Session
- and to convert exceptions in such a scenario; similar methods are also
- available as static helpers on the
- SessionFactoryUtils class. Note that such code will
- usually pass 'false' as the value of the
- DoGetSession(..) method's
- 'allowCreate' argument, to enforce running within a
- transaction (which avoids the need to close the returned
- Session, as its lifecycle is managed by the
- transaction). Asking for the
-
- public class HibernateProductDao : HibernateDaoSupport, IProductDao {
-
- public Customer SaveOrUpdate(Customer customer)
- {
- ISession session = DoGetSession(false);
- session.SaveOrUpdate(customer);
- return customer;
- }
- }
-}
-
- This code will not translate the Hibernate
- exception to a generic DataAccessException.
+ Introduced in Hibernate 2.1 is support for dependency
+ injection of hibernate managed objects via the
+ IBytecodeProvider extension point. As of Spring
+ 1.3 provides
+ Spring.Data.NHibernate.Bytecode.BytecodeProvider
+ as the default IBytecodeProvider implementation
+ when using LocalSessionFactory object to
+ configure an ISessionFactory. To use a
+ different IBytecodeProvider configure it via
+ the standard the Hibernate means, using App.confg or Web.config via
+ the element <bytecode-provider type="..."/>
+ inside the
+ <hibernate-configuration> section or
+ progammatically by setting
+ Environment.BytecodeProvider.
+
- Implementing DAOs based on plain Hibernate 1.2/2.0 API
+ Implementing DAOs based on plain Hibernate 1.2/2.x APIHibernate 1.2 introduced a feature called "contextual Sessions",
where Hibernate itself manages one current ISession
@@ -718,89 +591,156 @@ public class HibernateCustomerDao : ICustomerDao {
-
- Programmatic transaction demarcation
+
+ The HibernateTemplate for Hibernate
+ 1.2
- Transactions can be demarcated in a higher level of the
- application, on top of such lower-level data access services spanning
- any number of operations. There are no restrictions on the
- implementation of the surrounding business service here as well, it just
- needs a Spring PlatformTransactionManager. Again, the
- latter can come from anywhere, but preferably as an object reference via
- a TransactionManager property - just like the
- productDAO should be set via a
- setProductDao(..) method. The following
- snippets show a transaction manager and a business service definition in
- a Spring application context, and an example for a business method
- implementation.
+ The basic programming model for templating looks as follows for
+ methods that can be part of any custom data access object or business
+ service. There are no restrictions on the implementation of the
+ surrounding object at all, it just needs to provide a Hibernate
+ SessionFactory. It can get the latter from anywhere,
+ but preferably as an object reference from a Spring IoC container - via
+ a simple SessionFactory property setter. The
+ following snippets show a DAO definition in a Spring container,
+ referencing the above defined SessionFactory, and an
+ example for a DAO method implementation.<objects>
- <object id="TransactionManager"
- type="Spring.Data.NHibernate.HibernateTransactionManager, Spring.Data.NHibernate">
-
- <property name="DbProvider" ref="DbProvider"/>
+ <object id="CustomerDao" type="Spring.Northwind.Dao.NHibernate.HibernateCustomerDao, Spring.Northwind.Dao.NHibernate">
<property name="SessionFactory" ref="MySessionFactory"/>
-
</object>
- <!-- DAO definition not listed, see above for an example. -->
-
- <object id="FulfillmentService" type="Spring.Northwind.Service.FulfillmentService, Spring.Northwind.Service">
- <property name="CustomerDao" ref="CustomerDao"/>
- <property name="OrderDao" ref="OrderDao"/>
- <property name="ShippingService" ref="ShippingService"/>
- <property name="TransactionManager" ref="TransactionManager"/>
- </object>
-
-
</objects>
- public class FulfillmentService : IFulfillmentService
+
- private TransactionTemplate transactionTemplate;
+ public class HibernateCustomerDao : ICustomerDao {
- private IProductDao productDao;
+ private HibernateTemplate hibernateTemplate;
- private ICustomerDao customerDao;
+ public ISessionFactory SessionFactory
+ {
+ set { hibernateTemplate = new HibernateTemplate(value); }
+ }
- private IOrderDao orderDao;
+ public Customer SaveOrUpdate(Customer customer)
+ {
+ hibernateTemplate.SaveOrUpdate(customer);
+ return customer;
+ }
+}
- private IShippingService shippingService;
+ The HibernateTemplate class provides many
+ methods that mirror the methods exposed on the Hibernate
+ Session interface, in addition to a number of
+ convenience methods such as the one shown above. If you need access to
+ the Session to invoke methods that are not exposed on
+ the HibernateTemplate, you can always drop down to a
+ callback-based approach like so.
+ public class HibernateCustomerDao : ICustomerDao {
- public TransactionManager TransactionManager
+ private HibernateTemplate hibernateTemplate;
+
+ public ISessionFactory SessionFactory
+ {
+ set { hibernateTemplate = new HibernateTemplate(value); }
+ }
+
+ public Customer SaveOrUpdate(Customer customer)
+ {
+ return HibernateTemplate.Execute(
+ delegate(ISession session)
+ {
+ // do whatever you want with the session....
+ session.SaveOrUpdate(customer);
+ return customer;
+ }) as Customer;
+ }
+
+}
+
+ Using the anonymous delegate is particularly convenient when you
+ would otherwise be passing various method parameter calls to the
+ interface based version of this callback. Furthermore, when using
+ generics, you can avoid the typecast and write code like the
+ following
+
+ IList<Supplier> suppliers = HibernateTemplate.ExecuteFind<Supplier>(
+ delegate(ISession session)
+ {
+ return session.CreateQuery("from Supplier s were s.Code = ?")
+ .SetParameter(0, code)
+ .List<Supplier>();
+ });
+
+ where code is a variable in the surrounding block, accessible
+ inside the anonymous delegate implementation.
+
+ A callback implementation effectively can be used for any
+ Hibernate data access. HibernateTemplate will ensure
+ that Session instances are properly opened and
+ closed, and automatically participate in transactions. The template
+ instances are thread-safe and reusable, they can thus be kept as
+ instance variables of the surrounding class. For simple single step
+ actions like a single Find, Load, SaveOrUpdate, or Delete call,
+ HibernateTemplate offers alternative convenience
+ methods that can replace such one line callback implementations.
+ Furthermore, Spring provides a convenient
+ HibernateDaoSupport base class that provides a
+ SessionFactory property for receiving a
+ SessionFactory and for use by subclasses. In
+ combination, this allows for very simple DAO implementations for typical
+ requirements:
+
+ public class HibernateCustomerDao : HibernateDaoSupport, ICustomerDao
+{
+ public Customer SaveOrUpdate(Customer customer)
{
- set { transactionTemplate = new TransactionTemplate(value);
- }
- public void ProcessCustomer(string customerId)
- {
- tt.Execute(delegate(ITransactionStatus status)
- {
- //Find all orders for customer
- Customer customer = CustomerDao.FindById(customerId);
- foreach (Order order in customer.Orders)
- {
- //Validate Order
- Validate(order);
-
- //Ship with external shipping service
- ShippingService.ShipOrder(order);
-
- //Update shipping date
- order.ShippedDate = DateTime.Now;
-
- //Update shipment date
- OrderDao.SaveOrUpdate(order);
-
- //Other operations...Decrease product quantity... etc
- }
- return null;
- });
+ HibernateTemplate.SaveOrUpdate(customer);
+ return customer;
}
}
+
+ Implementing Spring-based DAOs without HibernateTemplate in
+ Hibernate 1.2
+
+ As an alternative to using Spring's
+ HibernateTemplate to implement DAOs, data access code
+ can also be written in a more traditional fashion, without wrapping the
+ Hibernate access code in a callback, while still respecting and
+ participating in Spring's generic DataAccessException
+ hierarchy. The HibernateDaoSupport base class offers
+ methods to access the current transactional Session
+ and to convert exceptions in such a scenario; similar methods are also
+ available as static helpers on the
+ SessionFactoryUtils class. Note that such code will
+ usually pass 'false' as the value of the
+ DoGetSession(..) method's
+ 'allowCreate' argument, to enforce running within a
+ transaction (which avoids the need to close the returned
+ Session, as its lifecycle is managed by the
+ transaction). Asking for the
+
+ public class HibernateProductDao : HibernateDaoSupport, IProductDao {
+
+ public Customer SaveOrUpdate(Customer customer)
+ {
+ ISession session = DoGetSession(false);
+ session.SaveOrUpdate(customer);
+ return customer;
+ }
+ }
+}
+
+ This code will not translate the Hibernate
+ exception to a generic DataAccessException.
+
+
Declarative transaction demarcation
@@ -926,6 +866,89 @@ public class HibernateCustomerDao : ICustomerDao {
configuration of other features, such as rollback rules.
+
+ Programmatic transaction demarcation
+
+ Transactions can be demarcated in a higher level of the
+ application, on top of such lower-level data access services spanning
+ any number of operations. There are no restrictions on the
+ implementation of the surrounding business service here as well, it just
+ needs a Spring PlatformTransactionManager. Again, the
+ latter can come from anywhere, but preferably as an object reference via
+ a TransactionManager property - just like the
+ productDAO should be set via a
+ setProductDao(..) method. The following
+ snippets show a transaction manager and a business service definition in
+ a Spring application context, and an example for a business method
+ implementation.
+
+ <objects>
+
+ <object id="TransactionManager"
+ type="Spring.Data.NHibernate.HibernateTransactionManager, Spring.Data.NHibernate">
+
+ <property name="DbProvider" ref="DbProvider"/>
+ <property name="SessionFactory" ref="MySessionFactory"/>
+
+ </object>
+
+ <!-- DAO definition not listed, see above for an example. -->
+
+ <object id="FulfillmentService" type="Spring.Northwind.Service.FulfillmentService, Spring.Northwind.Service">
+ <property name="CustomerDao" ref="CustomerDao"/>
+ <property name="OrderDao" ref="OrderDao"/>
+ <property name="ShippingService" ref="ShippingService"/>
+ <property name="TransactionManager" ref="TransactionManager"/>
+ </object>
+
+
+</objects>
+
+ public class FulfillmentService : IFulfillmentService
+
+ private TransactionTemplate transactionTemplate;
+
+ private IProductDao productDao;
+
+ private ICustomerDao customerDao;
+
+ private IOrderDao orderDao;
+
+ private IShippingService shippingService;
+
+
+ public TransactionManager TransactionManager
+ {
+ set { transactionTemplate = new TransactionTemplate(value);
+ }
+ public void ProcessCustomer(string customerId)
+ {
+ tt.Execute(delegate(ITransactionStatus status)
+ {
+ //Find all orders for customer
+ Customer customer = CustomerDao.FindById(customerId);
+ foreach (Order order in customer.Orders)
+ {
+ //Validate Order
+ Validate(order);
+
+ //Ship with external shipping service
+ ShippingService.ShipOrder(order);
+
+ //Update shipping date
+ order.ShippedDate = DateTime.Now;
+
+ //Update shipment date
+ OrderDao.SaveOrUpdate(order);
+
+ //Other operations...Decrease product quantity... etc
+ }
+ return null;
+ });
+ }
+}
+
+
Transaction management strategies
@@ -1035,9 +1058,10 @@ public class HibernateCustomerDao : ICustomerDao {
... do multiple operations with a single session, possibly in multiple transactions.
}
- At the end of the using block the session is automatically closed.
- All transactions within the scope use the same session, if you are using
- Spring's HibernateTemplate or using Spring's implementation of
+ Refer to the API documentation for information on overloaded
+ constructor. At the end of the using block the session is automatically
+ closed. All transactions within the scope use the same session, if you
+ are using Spring's HibernateTemplate or using Spring's implementation of
NHibernate 1.2's ICurrentSessionContext interface. See other sections in
this chapter for further information on those usage scenarios.
diff --git a/src/Spring/Spring.Data.NHibernate20/Data/NHibernate/LocalSessionFactoryObject.cs b/src/Spring/Spring.Data.NHibernate20/Data/NHibernate/LocalSessionFactoryObject.cs
index acf94671..8a6171d4 100644
--- a/src/Spring/Spring.Data.NHibernate20/Data/NHibernate/LocalSessionFactoryObject.cs
+++ b/src/Spring/Spring.Data.NHibernate20/Data/NHibernate/LocalSessionFactoryObject.cs
@@ -88,10 +88,6 @@ namespace Spring.Data.NHibernate
private string[] configFilenames;
- ///
- /// TODO: consider changing to NamevalueCollection for easier
- /// cut-n-paste from existing App.config based configurations.
- ///
private IDictionary hibernateProperties;
private IDbProvider dbProvider;
diff --git a/src/Spring/Spring.Data.NHibernate21/Data/NHibernate/Bytecode/BytecodeProvider.cs b/src/Spring/Spring.Data.NHibernate21/Data/NHibernate/Bytecode/BytecodeProvider.cs
index 6de27b0c..7f69543e 100644
--- a/src/Spring/Spring.Data.NHibernate21/Data/NHibernate/Bytecode/BytecodeProvider.cs
+++ b/src/Spring/Spring.Data.NHibernate21/Data/NHibernate/Bytecode/BytecodeProvider.cs
@@ -33,7 +33,7 @@ using Spring.Objects.Factory;
namespace Spring.Data.NHibernate.Bytecode
{
///
- ///
+ /// Bytecode provider using Spring Proxy
///
/// Fabio Maulo
public class BytecodeProvider : IBytecodeProvider