SPRNET-1299 - Move older ways of configuring transaction management, using HibernateTemplate, to a 'Classic Spring Usage' section
This commit is contained in:
@@ -591,155 +591,6 @@ public class HibernateCustomerDao : ICustomerDao {
|
||||
</section>
|
||||
</section>
|
||||
|
||||
<section xml:id="orm-hibernate-template">
|
||||
<title>The <literal>HibernateTemplate</literal> for Hibernate
|
||||
1.2</title>
|
||||
|
||||
<para>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
|
||||
<literal>SessionFactory</literal>. It can get the latter from anywhere,
|
||||
but preferably as an object reference from a Spring IoC container - via
|
||||
a simple <methodname>SessionFactory</methodname> property setter. The
|
||||
following snippets show a DAO definition in a Spring container,
|
||||
referencing the above defined <literal>SessionFactory</literal>, and an
|
||||
example for a DAO method implementation.</para>
|
||||
|
||||
<programlisting language="myxml"><objects>
|
||||
|
||||
<object id="CustomerDao" type="Spring.Northwind.Dao.NHibernate.HibernateCustomerDao, Spring.Northwind.Dao.NHibernate">
|
||||
<property name="SessionFactory" ref="MySessionFactory"/>
|
||||
</object>
|
||||
|
||||
</objects></programlisting>
|
||||
|
||||
<para></para>
|
||||
|
||||
<programlisting language="csharp">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;
|
||||
}
|
||||
}</programlisting>
|
||||
|
||||
<para>The <literal>HibernateTemplate</literal> class provides many
|
||||
methods that mirror the methods exposed on the Hibernate
|
||||
<literal>Session</literal> interface, in addition to a number of
|
||||
convenience methods such as the one shown above. If you need access to
|
||||
the <literal>Session</literal> to invoke methods that are not exposed on
|
||||
the <literal>HibernateTemplate</literal>, you can always drop down to a
|
||||
callback-based approach like so.</para>
|
||||
|
||||
<programlisting language="csharp">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;
|
||||
}
|
||||
|
||||
}</programlisting>
|
||||
|
||||
<para>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</para>
|
||||
|
||||
<programlisting language="csharp">IList<Supplier> suppliers = HibernateTemplate.ExecuteFind<Supplier>(
|
||||
delegate(ISession session)
|
||||
{
|
||||
return session.CreateQuery("from Supplier s were s.Code = ?")
|
||||
.SetParameter(0, code)
|
||||
.List<Supplier>();
|
||||
});</programlisting>
|
||||
|
||||
<para>where code is a variable in the surrounding block, accessible
|
||||
inside the anonymous delegate implementation.</para>
|
||||
|
||||
<para>A callback implementation effectively can be used for any
|
||||
Hibernate data access. <literal>HibernateTemplate</literal> will ensure
|
||||
that <literal>Session</literal> 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,
|
||||
<literal>HibernateTemplate</literal> offers alternative convenience
|
||||
methods that can replace such one line callback implementations.
|
||||
Furthermore, Spring provides a convenient
|
||||
<literal>HibernateDaoSupport</literal> base class that provides a
|
||||
<methodname>SessionFactory</methodname> property for receiving a
|
||||
<literal>SessionFactory</literal> and for use by subclasses. In
|
||||
combination, this allows for very simple DAO implementations for typical
|
||||
requirements:</para>
|
||||
|
||||
<programlisting language="csharp">public class HibernateCustomerDao : HibernateDaoSupport, ICustomerDao
|
||||
{
|
||||
public Customer SaveOrUpdate(Customer customer)
|
||||
{
|
||||
HibernateTemplate.SaveOrUpdate(customer);
|
||||
return customer;
|
||||
}
|
||||
}</programlisting>
|
||||
</section>
|
||||
|
||||
<section xml:id="orm-hibernate-daos">
|
||||
<title>Implementing Spring-based DAOs without HibernateTemplate in
|
||||
Hibernate 1.2</title>
|
||||
|
||||
<para>As an alternative to using Spring's
|
||||
<literal>HibernateTemplate</literal> 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 <literal>DataAccessException</literal>
|
||||
hierarchy. The <literal>HibernateDaoSupport</literal> base class offers
|
||||
methods to access the current transactional <literal>Session</literal>
|
||||
and to convert exceptions in such a scenario; similar methods are also
|
||||
available as static helpers on the
|
||||
<literal>SessionFactoryUtils</literal> class. Note that such code will
|
||||
usually pass '<literal>false</literal>' as the value of the
|
||||
<methodname>DoGetSession(..)</methodname> method's
|
||||
'<literal>allowCreate</literal>' argument, to enforce running within a
|
||||
transaction (which avoids the need to close the returned
|
||||
<literal>Session</literal>, as its lifecycle is managed by the
|
||||
transaction). Asking for the</para>
|
||||
|
||||
<programlisting language="csharp">public class HibernateProductDao : HibernateDaoSupport, IProductDao {
|
||||
|
||||
public Customer SaveOrUpdate(Customer customer)
|
||||
{
|
||||
ISession session = DoGetSession(false);
|
||||
session.SaveOrUpdate(customer);
|
||||
return customer;
|
||||
}
|
||||
}
|
||||
}</programlisting>
|
||||
|
||||
<para>This code will <emphasis>not</emphasis> translate the Hibernate
|
||||
exception to a generic <literal>DataAccessException</literal>.</para>
|
||||
</section>
|
||||
|
||||
<section xml:id="orm-hibernate-tx-declarative">
|
||||
<title>Declarative transaction demarcation</title>
|
||||
|
||||
Reference in New Issue
Block a user