More About Model-View-Controller Architecture : Struts1.1
More About Model-View-Controller Architecture : Struts1.1
1
1.What is MVC?
Model-View-Controller (MVC) is a design pattern put together to help control change. MVC
decouples interface from business logic and data.
• Model : The model contains the core of the application's functionality. The model
encapsulates the state of the application. Sometimes the only functionality it contains
is state. It knows nothing about the view or controller.
• View: The view provides the presentation of the model. It is the look of the
application. The view can access the model getters, but it has no knowledge of the
setters. In addition, it knows nothing about the controller. The view should be notified
when changes to the model occur.
• Controller:The controller reacts to the user input. It creates and sets the model.
2.What is a framework?
A framework is made up of the set of classes which allow us to use a library in a best possible
way for a specific requirement.
3.What is Struts framework?
Struts framework is an open-source framework for developing the web applications in Java EE,
based on MVC-2 architecture. It uses and extends the Java Servlet API. Struts is robust
architecture and can be used for the development of application of any size. Struts framework
makes it much easier to design scalable, reliable Web applications with Java.
4.What are the components of Struts?
Struts components can be categorize into Model, View and Controller:
• Model: Components like business logic /business processes and data are the part of
model.
• View: HTML, JSP are the view components.
• Controller: Action Servlet of Struts is part of Controller components which works as
front controller to handle all the requests.
6.What is ActionServlet?
ActionServlet is a simple servlet which is the backbone of all Struts applications. It is the main
Controller component that handles client requests and determines which Action will process
each received request. It serves as an Action factory – creating specific Action classes based on
user’s request.
1
7.What is role of ActionServlet?
ActionServlet performs the role of Controller:
reset(): reset() method is called by Struts Framework with each request that uses the defined
ActionForm. The purpose of this method is to reset all of the ActionForm's data members prior
to the new request values being set.
11.What is ActionMapping?
Action mapping contains all the deployment information for a particular Action bean. This class
is to determine where the results of the Action will be sent once its processing is complete.
<action-mappings>
<action path="/submit"
type="submit.SubmitAction"
name="submitForm"
2
input="/submit.jsp"
scope="request"
validate="true">
<forward name="success" path="/success.jsp"/>
<forward name="failure" path="/error.jsp"/>
</action>
</action-mappings>
• Service to Worker
• Dispatcher View
• Composite View (Struts Tiles)
• Front Controller
• View Helper
• Synchronizer Token
3
16.Can we have more than one struts-config.xml file for a single Struts application?
Yes, we can have more than one struts-config.xml for a single Struts application. They can be
configured as follows:
<servlet>
<servlet-name>action</servlet-name>
<servlet-class>
org.apache.struts.action.ActionServlet
</servlet-class>
<init-param>
<param-name>config</param-name>
<param-value>
/WEB-INF/struts-config.xml,
/WEB-INF/struts-admin.xml,
/WEB-INF/struts-config-forms.xml
</param-value>
</init-param>
.....
<servlet>
4
18.What is the difference between session scope and request scope when saving
formbean ?
when the scope is request,the values of formbean would be available for the current request.
when the scope is session,the values of formbean would be available throughout the session.
19.What are the important tags of struts-config.xml ?
The five important sections are:
5
20.What are the different kinds of actions in Struts?
The different kinds of actions in Struts are:
• ForwardAction
• IncludeAction
• DispatchAction
• LookupDispatchAction
• SwitchAction
21.What is DispatchAction?
The DispatchAction class is used to group related actions into one class. Using this class, you
can have a method for each logical action compared than a single execute method. The
DispatchAction dispatches to one of the logical actions represented by the methods. It picks a
6
method to invoke based on an incoming request parameter. The value of the incoming
parameter is the name of the method that the DispatchAction will invoke.
DispatchAction Example »
24.What is IncludeAction?
The IncludeAction class is useful when you want to integrate Struts into an application that
uses Servlets. Use the IncludeAction class to include another resource in the response to the
request being processed.
26.What is LookupDispatchAction?
The LookupDispatchAction is a subclass of DispatchAction. It does a reverse lookup on the
resource bundle to get the key and then gets the method whose name is associated with the
key into the Resource Bundle.
7
The difference between LookupDispatchAction and DispatchAction is that the actual method
that gets called in LookupDispatchAction is based on a lookup of a key value instead of
specifying the method name directly.
29.What is SwitchAction?
The SwitchAction class provides a means to switch from a resource in one module to another
resource in a different module. SwitchAction is useful only if you have multiple modules in your
Struts application. The SwitchAction class can be used as is, without extending.
30.What if <action> element has <forward> declaration with same name as global forward?
In this case the global forward is not used. Instead the <action> element’s <forward> takes
precendence.
31.What is DynaActionForm?
A specialized subclass of ActionForm that allows the creation of form beans with dynamic sets
of properties (configured in configuration file), without requiring the developer to create a
Java class for each type of form bean.
<form-bean
name="loginForm"type="org.apache.struts.action.DynaActionForm" >
<form-property name="userName" type="java.lang.String"/>
<form-property name="password" type="java.lang.String" />
</form-bean>
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
8
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionMessage;
import org.apache.struts.action.ActionMessages;
import org.apache.struts.action.DynaActionForm;
if (((String) loginForm.get("userName")).equals("")) {
errors.add("userName", new ActionMessage(
"error.userName.required"));
}
if (((String) loginForm.get("password")).equals("")) {
errors.add("password", new ActionMessage(
"error.password.required"));
}
...........
• HTML Tags
• Bean Tags
• Logic Tags
• Template Tags
• Nested Tags
• Tiles Tags
9
35.What is the use of <logic:iterate>?
<logic:iterate> repeats the nested body content of this tag over a specified collection.
<table border=1>
<logic:iterate id="customer" name="customers">
<tr>
<td><bean:write name="customer" property="firstName"/></td>
<bean:write>: is used to retrieve and print the value of the bean property. <bean:write> has
no body.
<bean:write name="customer" property="firstName"/>
• Programmatic exception handling : Explicit try/catch blocks in any code that can
throw exception. It works well when custom value (i.e., of variable) needed when error
occurs.
<global-exceptions>
<exception key="some.key"
type="java.lang.NullPointerException"
path="/WEB-INF/errors/null.jsp"/>
</global-exceptions>
10
or
<exception key="some.key"
type="package.SomeException"
path="/WEB-INF/somepage.jsp"/>
• An ActionForm represents an HTML form that the user interacts with over one or more
pages. You will provide properties to hold the state of the form with getters and
setters to access them. Whereas, using DynaActionForm there is no need of providing
properties to hold the state. Instead these properties and their type are declared in
the struts-config.xml
•
• The DynaActionForm bloats up the Struts config file with the xml based definition. This
gets annoying as the Struts Config file grow larger.
•
• The DynaActionForm is not strongly typed as the ActionForm. This means there is no
compile time checking for the form fields. Detecting them at runtime is painful and
makes you go through redeployment.
•
• ActionForm can be cleanly organized in packages as against the flat organization in the
Struts Config file.
•
• ActionForm were designed to act as a Firewall between HTTP and the Action classes,
i.e. isolate and encapsulate the HTTP request parameters from direct use in Actions.
• With DynaActionForm, the property access is no different than using
request.getParameter( .. ).
•
• DynaActionForm construction at runtime requires a lot of Java Reflection
(Introspection) machinery that can be avoided.
11
Spring
The basic concept of the Inversion of Control pattern (also known as dependency injection) is
that you do not create your objects but describe how they should be created. You don't
directly connect your components and services together in code but describe which services
are needed by which components in a configuration file. A container (in the case of the Spring
framework, the IOC container) is then responsible for hooking it all up.
i.e., Applying IoC, objects are given their dependencies at creation time by some external
entity that coordinates each object in the system. That is, dependencies are injected into
objects. So, IoC means an inversion of responsibility with regard to how an object obtains
references to collaborating objects.
2. What are the different types of IOC (dependency injection) ?
There are three types of dependency injection:
• Constructor Injection (e.g. Pico container, Spring etc): Dependencies are provided as
constructor parameters.
• Setter Injection (e.g. Spring): Dependencies are assigned through JavaBeans properties
(ex: setter methods).
• Interface Injection (e.g. Avalon): Injection is done through an interface. Note: Spring
supports only Constructor and Setter Injection
12
the Spring framework is its layered architecture, which allows you to be selective about which
of its components you use while also providing a cohesive framework for J2EE application
development.
• Spring has layered architecture. Use what you need and leave you don't need now.
• Spring Enables POJO Programming. There is no behind the scene magic here. POJO
programming enables continuous integration and testability.
• Dependency Injection and Inversion of Control Simplifies JDBC
• Open source and no vendor lock-in.
• Lightweight:
spring is lightweight when it comes to size and transparency. The basic version of
spring framework is around 1MB. And the processing overhead is also very negligible.
Loose coupling is achieved in spring using the technique Inversion of Control. The
objects give their dependencies instead of creating or looking for dependent objects.
• Container:
Spring contains and manages the life cycle and configuration of application objects.
• MVC Framework:
Spring comes with MVC web application framework, built on core Spring functionality.
This framework is highly configurable via strategy interfaces, and accommodates
multiple view technologies like JSP, Velocity, Tiles, iText, and POI. But other
frameworks can be easily used instead of Spring MVC Framework.
• Transaction Management:
13
The JDBC abstraction layer of the Spring offers a (Roll over to view the Image )
meaningful exception hierarchy, which simplifies
the error handling strategy. Integration with
Hibernate, JDO, and iBATIS: Spring provides best
Integration services with Hibernate, JDO and
iBATIS
7. How many modules are there in Spring? What are
they?
Spring comprises of seven modules. They are..
The core container provides the essential functionality of the Spring framework. A
primary component of the core container is the BeanFactory, an implementation of
the Factory pattern. The BeanFactory applies the Inversion of Control (IOC) pattern to
separate an application's configuration and dependency specification from the actual
application code.
• Spring context:
The Spring context is a configuration file that provides context information to the
Spring framework. The Spring context includes enterprise services such as JNDI, EJB, e-
mail, internalization, validation, and scheduling functionality.
• Spring AOP:
• Spring DAO:
The Spring JDBC DAO abstraction layer offers a meaningful exception hierarchy for
managing the exception handling and error messages thrown by different database
vendors. The exception hierarchy simplifies error handling and greatly reduces the
amount of exception code you need to write, such as opening and closing connections.
Spring DAO's JDBC-oriented exceptions comply to its generic DAO exception hierarchy.
• Spring ORM:
The Spring framework plugs into several ORM frameworks to provide its Object
Relational tool, including JDO, Hibernate, and iBatis SQL Maps. All of these comply to
Spring's generic transaction and DAO exception hierarchies.
The Web context module builds on top of the application context module, providing
contexts for Web-based applications. As a result, the Spring framework supports
14
integration with Jakarta Struts. The Web module also eases the tasks of handling multi-
part requests and binding request parameters to domain objects.
• Setter Injection:
Setter-based DI is realized by calling setter methods on your beans after invoking a no-
argument constructor or no-argument static factory method to instantiate your bean.
• Constructor Injection:
11. What is the difference between Bean Factory and Application Context ?
On the surface, an application context is same as a bean factory. But application context offers
much more..
15
• Application contexts provide a means for resolving text messages, including support for
i18n of those messages.
• Application contexts provide a generic way to load file resources, such as images.
• Application contexts can publish events to beans that are registered as listeners.
• Certain operations on the container or beans in the container, which have to be
handled in a programmatic fashion with a bean factory, can be handled declaratively in
an application context.
• ResourceLoader support: Spring’s Resource interface us a flexible generic abstraction
for handling low-level resources. An application context itself is a ResourceLoader,
Hence provides an application with access to deployment-specific Resource instances.
• MessageSource support: The application context implements MessageSource, an
interface used to obtain localized messages, with the actual implementation being
pluggable
16
• If an init-method is specified for the bean, it will be called.
• Finally, if there are any BeanPostProcessors associated with the bean, their
postProcessAfterInitialization() methods will be called.
• DelegatingVariableResolver: Spring comes with a JSF variable resolver that lets you
use JSF and Spring together.
• <?xml version="1.0" encoding="UTF-8"?>
• "http://www.springframework.org/dtd/spring-beans.dtd">
•
• <faces-config>
• <application>
• <variable-resolver>
• org.springframework.web.jsf.DelegatingVariableResolver
• </variable-resolver>
• </application>
• </faces-config>
17
• The DelegatingVariableResolver will first delegate value lookups to the default resolver
of the underlying JSF implementation, and then to Spring's 'business context'
WebApplicationContext. This allows one to easily inject dependencies into one's JSF-
managed beans.
• FacesContextUtils:custom VariableResolver works well when mapping one's properties
to beans in faces-config.xml, but at times one may need to grab a bean explicitly. The
FacesContextUtils class makes this easy. It is similar to WebApplicationContextUtils,
except that it takes a FacesContext parameter rather than a ServletContext parameter.
• ApplicationContext ctx =
FacesContextUtils.getWebApplicationContext(FacesContext.getCurrentInstanc
e());
• Does a bean with the specified name already exist in some scope (request, session,
application)? If so, return it
• Is there a standard JavaServer Faces managed bean definition for this variable name? If
so, invoke it in the usual way, and return the bean that was created.
• Is there configuration information for this variable name in the Spring
WebApplicationContext for this application? If so, use it to create and configure an
instance, and return that instance to the caller.
• If there is no managed bean or Spring definition for this variable name, return null
instead.
• BeanFactory also takes part in the life cycle of a bean, making calls to custom
initialization and destruction methods.
As a result of this algorithm, you can transparently use either JavaServer Faces or
Spring facilities to create beans on demand.
18
Spring - JSF integration is useful when an event handler wishes to explicitly invoke the bean
factory to create beans on demand, such as a bean that encapsulates the business logic to be
performed when a submit button is pressed.
• Configure Spring to manage your Actions as beans, using the ContextLoaderPlugin, and
set their dependencies in a Spring context file.
• Subclass Spring's ActionSupport classes and grab your Spring-managed beans explicitly
using a getWebApplicationContext() method.
• Hibernate
• iBatis
• JPA (Java Persistence API)
• TopLink
• JDO (Java Data Objects)
• OJB
Scope Description
Scopes a single bean definition to a single object instance per Spring IoC
singleton
container.
19
Scope Description
Scopes a single bean definition to the lifecycle of a single HTTP request; that is
each and every HTTP request will have its own instance of a bean created off
request
the back of a single bean definition. Only valid in the context of a web-aware
Spring ApplicationContext.
Scopes a single bean definition to the lifecycle of a HTTP Session. Only valid
session
in the context of a web-aware Spring ApplicationContext.
20
Action taken by an aspect at a particular join point. Different types of advice include "around,"
"before" and "after" advice. Many AOP frameworks, including Spring, model an advice as an
interceptor, maintaining a chain of interceptors "around" the join point.
• Before advice: Advice that executes before a join point, but which does not have the
ability to prevent execution flow proceeding to the join point (unless it throws an
exception).
• After returning advice: Advice to be executed after a join point completes normally:
for example, if a method returns without throwing an exception.
• After throwing advice: Advice to be executed if a method exits by throwing an
exception.
• After (finally) advice: Advice to be executed regardless of the means by which a join
point exits (normal or exceptional return).
• Around advice: Advice that surrounds a join point such as a method invocation. This is
the most powerful kind of advice. Around advice can perform custom behavior before
and after the method invocation. It is also responsible for choosing whether to proceed
to the join point or to shortcut the advised method execution by returning its own
return value or throwing an exception
32. What are the types of the transaction management Spring supports ?
Spring Framework supports:
33. What are the benefits of the Spring Framework transaction management ?
The Spring Framework provides a consistent abstraction for transaction management that
delivers the following benefits:
• Provides a consistent programming model across different transaction APIs such as JTA,
JDBC, Hibernate, JPA, and JDO.
• Supports declarative transaction management.
• Provides a simpler API for programmatic transaction management than a number of
complex transaction APIs such as JTA.
• Integrates very well with Spring's various data access abstractions.
34. Why most users of the Spring Framework choose declarative transaction management ?
Most users of the Spring Framework choose declarative transaction management because it is
the option with the least impact on application code, and hence is most consistent with the
ideals of a non-invasive lightweight container.
35. Explain the similarities and differences between EJB CMT and the Spring Framework's
declarative transaction
management ?
21
The basic approach is similar: it is possible to specify transaction behavior (or lack of it)
down to individual method level. It is
possible to make a setRollbackOnly() call within a transaction
context if necessary. The differences are:
39. What are the exceptions thrown by the Spring DAO classes ?
Spring DAO classes throw exceptions which are subclasses of
DataAccessException(org.springframework.dao.DataAccessException).Spring provides a
convenient translation from technology-specific exceptions like SQLException to its own
exception class hierarchy with the DataAccessException as the root exception. These
exceptions wrap the original exception.
22
41. What is Spring's JdbcTemplate ?
Spring's JdbcTemplate is central class to interact with a database through JDBC. JdbcTemplate
provides many convenience methods for doing things such as converting database data into
primitives or objects, executing prepared and callable statements, and providing custom
database error handling.
JdbcTemplate template = new JdbcTemplate
• Cannot declaratively
23
define rollback
behavior—this must be
done
programmatically.
Persistence Supports programmatic bean- Provides a framework for integrating with
managed persistence and several persistence technologies, including
declarative container JDBC, Hibernate, JDO, and iBATIS.
managed persistence.
Declarative • Supports declarative • No security implementation out-of-
security security through users the box.
and roles. The
management and • Acegi, an open source security
implementation of framework built on top of Spring,
users and roles is provides declarative security through
container specific. the Spring configuration file or class
metadata.
• Declarative security is
configured in the
deployment
descriptor.
Distributed Provides container-managed Provides proxying for remote calls via RMI,
computing remote method calls. JAX-RPC, and web services.
Hibernate
1.What is ORM ?
ORM stands for object/relational mapping. ORM is the automated persistence of objects in a
Java application to the tables in a relational database.
4.What is Hibernate?
24
Hibernate is a pure Java object-relational mapping (ORM) and persistence framework
that allows you to map plain old Java objects to relational database tables using (XML)
configuration files.Its purpose is to relieve the developer from a significant amount of
relational data persistence-related programming tasks.
• Improved productivity
o High-level object-oriented API
o Less Java code to write
o No SQL to write
• Improved performance
o Sophisticated caching
o Lazy loading
o Eager loading
• Improved maintainability
o A lot less code to write
• Improved portability
o ORM framework generates database-specific SQL for you
25
8.What are the most common methods of Hibernate configuration?
The most common methods of Hibernate configuration are:
• Programmatic configuration
• XML configuration (hibernate.cfg.xml)
26
The five core interfaces are used in just about every Hibernate application. Using these
interfaces, you can store and retrieve persistent objects and control transactions.
• Session interface
• SessionFactory interface
• Configuration interface
• Transaction interface
• Query and Criteria interfaces
• Load the Hibernate configuration file and create configuration object. It will
automatically load all hbm mapping files
• Create session factory from configuration object
• Get one session from this session factory
• Create HQL Query
• Execute query to get list containing Java objects
27
• First we need to write Java domain objects (beans with setter and getter).
• Write hbm.xml, where we map java class to table and database columns to Java class
variables.
Example :
<hibernate-mapping>
<class name="com.test.User" table="user">
<property column="USER_NAME" length="255"
name="userName" not-null="true" type="java.lang.String"/>
<property column="USER_PASSWORD" length="255"
name="userPassword" not-null="true"
type="java.lang.String"/>
</class>
</hibernate-mapping>
Only use the load() method if you are sure If you are not sure that the object exists,
that the object exists. then use one of the get() methods.
load() method will throw an exception if the get() method will return null if the
unique id is not found in the database. unique id is not found in the database.
28
cascade - enable operations to cascade to child entities.
cascade="all|none|save-update|delete|all-delete-orphan"
29
22.Explain Criteria API
Criteria is a simplified API for retrieving entities by composing Criterion objects. This is a very
convenient approach for functionality like "search" screens where there is a variable number of
conditions to be placed upon the result set.
Example :
List employees = session.createCriteria(Employee.class)
.add(Restrictions.like("name", "a%") )
.add(Restrictions.like("address",
"Boston"))
.addOrder(Order.asc("name") )
.list();
23.Define HibernateTemplate?
org.springframework.orm.hibernate.HibernateTemplate is a helper class which provides
different methods for querying/retrieving data from the database. It also converts checked
HibernateExceptions into unchecked DataAccessExceptions.
26.If you want to see the Hibernate generated SQL statements on console, what should we
do?
In Hibernate configuration file set as follows:
<property name="show_sql">true</property>
•
28.What is component mapping in Hibernate?
30
• Required to define an empty constructor
• Shared references not supported
Example:
If your collection is not large, it will be more If your collection is very large, it will be
efficient way to sort it. more efficient way to sort it .
With JDBC, developer has to write code to Hibernate is flexible and powerful ORM
map an object model's data representation solution to map Java classes to database
31
tables. Hibernate itself takes care of this
to a relational data model and its
mapping using XML files so developer does
corresponding database schema.
not need to write code for this.
In JDBC there is no check that always every Hibernate enables developer to define
user has updated data. This check has to be version type field to application, due to this
added by the developer. defined field Hibernate updates version field
of database table every time relational tuple
is updated in form of Java class object to
that table. So if two users retrieve same
tuple and then modify it and one user save
32
this modified tuple to database, version is
automatically updated for this tuple by
Hibernate. When other user tries to save
updated tuple to database then it does not
allow saving it because this user does not
have updated data.
• Bag
• Set
• List
• Array
• Map
36.How can Hibernate be configured to access an instance variable directly and not
through a setter method ?
By mapping the property with access="field" in Hibernate metadata. This forces hibernate to
bypass the setter method and access the instance variable directly while initializing a newly
loaded object.
Mark the class as mutable="false" (Default is true),. This specifies that instances of the class
are (not) mutable. Immutable classes, may not be updated or deleted by the application.
33
38.What is the use of dynamic-insert and dynamic-update attributes in a class mapping?
Criteria is a simplified API for retrieving entities by composing Criterion objects. This is a very
convenient approach for functionality like "search" screens where there is a variable number of
conditions to be placed upon the result set.
•
42.What are Callback interfaces?
Callback interfaces allow the application to receive a notification when something interesting
happens to an object—for example, when an object is loaded, saved, or deleted. Hibernate
applications don't need to implement these callbacks, but they're useful for implementing
certain kinds of generic functionality.
34
Attribute Oriented Programming Attribute Oriented Programming
Provides callback support through lifecycle, Provides callback support through Entity
interceptor, and validatable interfaces Listener and Callback methods
Answer:
" hibernate.cfg.xml (alternatively can use hibernate.properties): These two files are used to
configure the hibernate sevice (connection driver class, connection URL, connection username,
connection password, dialect etc). If both files are present in the classpath then
hibernate.cfg.xml file overrides the settings found in the hibernate.properties file.
" Mapping files (*.hbm.xml): These files are used to map persistent objects to a relational
database. It is the best practice to store each object in an individual mapping file (i.e mapping
file per class) because storing large number of persistent classes into one mapping file can be
difficult to manage and maintain. The naming convention is to use the same name as the
persistent (POJO) class name. For example Account.class will have a mapping file named
Account.hbm.xml. Alternatively hibernate annotations can be used as part of your persistent
class code instead of the *.hbm.xml files.
Answer:
35
SessionFactory is Hibernates concept of a single datastore and is threadsafe so that many
threads can access it concurrently and request for sessions and immutable cache of compiled
mappings for a single database. A SessionFactory is usually only built once at startup.
SessionFactory should be wrapped in some kind of singleton so that it can be easily accessed
in an application code.
Q. What is a Session? Can you share a session object between different theads?
Answer:
Session is a light weight and a non-threadsafe object (No, you cannot share it between
threads) that represents a single unit-of-work with the database. Sessions are opened by a
SessionFactory and then are closed when all work is complete. Session is the primary interface
for the persistence service. A session obtains a database connection lazily (i.e. only when
required). To avoid creating too many sessions ThreadLocal class can be used as shown below
to get the current session no matter how many times you make call to the currentSession()
method.
&
public class HibernateUtil {
&
public static final ThreadLocal local = new ThreadLocal();
It is also vital that you close your session after your unit of work completes. Note: Keep your
Hibernate Session API handy.
Answer:
Detached objects can be passed across layers all the way up to the presentation layer without
having to use any DTOs (Data Transfer Objects). You can later on re-attach the detached
objects to another session.
Answer:
Pros:
" When long transactions are required due to user think-time, it is the best practice to break
the long transaction up into two or more transactions. You can use detached objects from the
first transaction to carry data all the way up to the presentation layer. These detached objects
36
get modified outside a transaction and later on re-attached to a new transaction via another
session.
Cons
" In general, working with detached objects is quite cumbersome, and better to not clutter up
the session with them if possible. It is better to discard them and re-fetch them on subsequent
requests. This approach is not only more portable but also more efficient because - the objects
hang around in Hibernate's cache anyway.
" Also from pure rich domain driven design perspective it is recommended to use DTOs
(DataTransferObjects) and DOs (DomainObjects) to maintain the separation between Service
and UI tiers.
Q. How does Hibernate distinguish between transient (i.e. newly instantiated) and
detached objects?
Answer
Q. What is the difference between the session.get() method and the session.load() method?
Both the session.get(..) and session.load() methods create a persistent object by loading the required
object from the database. But if there was not such object in the database then the method
session.load(..) throws an exception whereas session.get(&) returns null.
Q. What is the difference between the session.update() method and the session.lock() method?
Both of these methods and saveOrUpdate() method are intended for reattaching a detached object. The
session.lock() method simply reattaches the object to the session without checking or updating the
database on the assumption that the database in sync with the detached object. It is the best practice to
use either session.update(..) or session.saveOrUpdate(). Use session.lock() only if you are absolutely sure
that the detached object is in sync with your detached object or if it does not matter because you will be
overwriting all the columns that would have changed later on within the same transaction.
Note: When you reattach detached objects you need to make sure that the dependent objects are
reatched as well.
Q. How would you reatach detached objects to a session when the same object has already
been loaded into the session?
Q. What are the general considerations or best practices for defining your Hibernate persistent
classes?
1.You must have a default no-argument constructor for your persistent classes and there should be
getXXX() (i.e accessor/getter) and setXXX( i.e. mutator/setter) methods for all your persistable instance
variables.
2.You should implement the equals() and hashCode() methods based on your business key and it is
important not to use the id field in your equals() and hashCode() definition if the id field is a surrogate key
37
(i.e. Hibernate managed identifier). This is because the Hibernate only generates and sets the field when
saving the object.
3. It is recommended to implement the Serializable interface. This is potentially useful if you want to
migrate around a multi-processor cluster.
4.The persistent class should not be final because if it is final then lazy loading cannot be used by creating
proxy objects.
5.Use XDoclet tags for generating your *.hbm.xml files or Annotations (JDK 1.5 onwards), which are less
verbose than *.hbm.xml files.
select user
from User user
left join user.messages msg
group by user
order by count(msg)
or:
38
If not, and in the case of a one-to-many or many-to-many association:
select user
from User user
join user.messages msg
group by user
having count(msg) >= 1
Because of the inner join, this form can't be used to return a User with zero messages, so the following form is
also useful
select user
from User as user
left join user.messages as msg
group by user
having count(msg) = 0
select box
from Box box
left join box.balls ball
where ball is null
1. Use a SortedSet or SortedMap, specifying a comparator class in the sort attribute or <set> or <map>. This
solution does a sort in memory.
2. Specify an order-by attribute of <set>, <map> or <bag>, naming a list of table columns to sort by. This
solution works only in JDK 1.4+.
39
Query q = s.createFilter( collection, "" ); // the trivial filter
q.setMaxResults(PAGE_SIZE);
q.setFirstResult(PAGE_SIZE * pageNumber);
List page = q.list();
you could use this collection mapping (inside the mapping for class Foo):
<set name="relationship">
<key column="fk_of_foo"/>
<composite-element class="Relationship">
<property name="multiplicity" type="short" not-null="true"/>
<property name="created" type="date" not-null="true"/>
<many-to-one name="bar" class="Bar" not-null="true"/>
</composite-element>
</set>
You may also use an <idbag> with a surrogate key column for the collection table. This would allow you to have
nullable columns.
An alternative approach is to simply map the association table as a normal entity class with two bidirectional one-
to-many associations.
40
In an MVC application, how can we ensure that all proxies and lazy
collections will be initialized when the view tries to access them?
One possible approach is to leave the session open (and transaction uncommitted) when forwarding to the view.
The session/transaction would be closed/committed after the view is rendered in, for example, a servlet filter
(another example would by to use the ModelLifetime.discard() callback in Maverick). One difficulty with this
approach is making sure the session/transaction is closed/rolled back if an exception occurs rendering the view.
Another approach is to simply force initialization of all needed objects using Hibernate.initialize(). This is
often more straightforward than it sounds.
How can I trim spaces from String data persisted to a CHAR column?
Use a UserType.
41
How can I convert the type of a property to/from the database
column type?
Use a UserType.
How can I get access to O/R mapping information such as table and
column names at runtime?
This information is available via the Configuration object. For example, entity mappings may be obtained using
Configuration.getClassMapping(). It is even possible to manipulate this metamodel at runtime and then
build a new SessionFactory.
This works if getItem() returns a proxy and if you mapped the identifier property with regular accessor methods.
If you enabled direct field access for the id of an Item, the Item proxy will be initialized if you call getId(). This
method is then treated like any other business method of the proxy, initialization is required if it is called.
Note that the SessionFactory is immutable and does not retain any reference to the Configuration instance,
so you must re-build it if you wish to activate the modified mappings.
How can I avoid n+1 SQL SELECT queries when running a Hibernate
query?
42
Follow the best practices guide! Ensure that all <class> and <collection> mappings specify lazy="true" in
Hibernate2 (this is the new default in Hibernate3). Use HQL LEFT JOIN FETCH to specify which associations you
need to be retrieved in the initial SQL SELECT.
A second way to avoid the n+1 selects problem is to use fetch="subselect" in Hibernate3.
If you are still unsure, refer to the Hibernate documentation and Hibernate in Action.
How can I insert XML data into Oracle using the xmltype() function?
Specify custom SQL INSERT (and UPDATE) statements using <sql-insert> and <sql-update> in Hibernate3,
or using a custom persister in Hibernate 2.1.
You will also need to write a UserType to perform binding to/from the PreparedStatement.
Or, in Hibernate3, override generated SQL using <sql-insert>, <sql-update>, <sql-delete> and
<loader> in the mapping document.
I want to call an SQL function from HQL, but the HQL parser does
not recognize it!
Subclass your Dialect, and call registerFunction() from the constructor.
43
Integer size = (Integer) s.createFilter( collection, "select
count(*)" ).uniqueResult();
select user
from User user
left join user.messages msg
group by user
order by count(msg)
or:
select user
from User user
join user.messages msg
group by user
having count(msg) >= 1
Because of the inner join, this form can't be used to return a User with zero messages, so the following form is
also useful
select user
from User as user
left join user.messages as msg
group by user
having count(msg) = 0
44
where box.balls is empty
select box
from Box box
left join box.balls ball
where ball is null
1. Use a SortedSet or SortedMap, specifying a comparator class in the sort attribute or <set> or <map>. This
solution does a sort in memory.
2. Specify an order-by attribute of <set>, <map> or <bag>, naming a list of table columns to sort by. This
solution works only in JDK 1.4+.
45
create table relationship (
fk_of_foo bigint not null,
fk_of_bar bigint not null,
multiplicity smallint,
created date )
you could use this collection mapping (inside the mapping for class Foo):
<set name="relationship">
<key column="fk_of_foo"/>
<composite-element class="Relationship">
<property name="multiplicity" type="short" not-null="true"/>
<property name="created" type="date" not-null="true"/>
<many-to-one name="bar" class="Bar" not-null="true"/>
</composite-element>
</set>
You may also use an <idbag> with a surrogate key column for the collection table. This would allow you to have
nullable columns.
An alternative approach is to simply map the association table as a normal entity class with two bidirectional one-
to-many associations.
In an MVC application, how can we ensure that all proxies and lazy
collections will be initialized when the view tries to access them?
One possible approach is to leave the session open (and transaction uncommitted) when forwarding to the view.
The session/transaction would be closed/committed after the view is rendered in, for example, a servlet filter
(another example would by to use the ModelLifetime.discard() callback in Maverick). One difficulty with this
approach is making sure the session/transaction is closed/rolled back if an exception occurs rendering the view.
Another approach is to simply force initialization of all needed objects using Hibernate.initialize(). This is
often more straightforward than it sounds.
46
Query q = s.createQuery("from foo in class Foo where foo.name=:name and
foo.size=:size");
q.setProperties(fooBean); // fooBean has getName() and getSize()
List foos = q.list();
How can I trim spaces from String data persisted to a CHAR column?
Use a UserType.
How can I get access to O/R mapping information such as table and
column names at runtime?
This information is available via the Configuration object. For example, entity mappings may be obtained using
Configuration.getClassMapping(). It is even possible to manipulate this metamodel at runtime and then
build a new SessionFactory.
47
session.save(bid);
This works if getItem() returns a proxy and if you mapped the identifier property with regular accessor methods.
If you enabled direct field access for the id of an Item, the Item proxy will be initialized if you call getId(). This
method is then treated like any other business method of the proxy, initialization is required if it is called.
Note that the SessionFactory is immutable and does not retain any reference to the Configuration instance,
so you must re-build it if you wish to activate the modified mappings.
How can I avoid n+1 SQL SELECT queries when running a Hibernate
query?
Follow the best practices guide! Ensure that all <class> and <collection> mappings specify lazy="true" in
Hibernate2 (this is the new default in Hibernate3). Use HQL LEFT JOIN FETCH to specify which associations you
need to be retrieved in the initial SQL SELECT.
A second way to avoid the n+1 selects problem is to use fetch="subselect" in Hibernate3.
If you are still unsure, refer to the Hibernate documentation and Hibernate in Action.
How can I insert XML data into Oracle using the xmltype() function?
Specify custom SQL INSERT (and UPDATE) statements using <sql-insert> and <sql-update> in Hibernate3,
or using a custom persister in Hibernate 2.1.
You will also need to write a UserType to perform binding to/from the PreparedStatement.
48
How can I execute arbitrary SQL using Hibernate?
PreparedStatement ps = session.connection().prepareStatement(sqlString);
Or, in Hibernate3, override generated SQL using <sql-insert>, <sql-update>, <sql-delete> and
<loader> in the mapping document.
I want to call an SQL function from HQL, but the HQL parser does
not recognize it!
Subclass your Dialect, and call registerFunction() from the constructor.
12.1. Introduction
The Spring Framework provides integration with Hibernate, JDO, Oracle TopLink,
iBATIS SQL Maps and JPA: in terms of resource management, DAO implementation
support, and transaction strategies. For example for Hibernate, there is first-class support
with lots of IoC convenience features, addressing many typical Hibernate integration
issues. All of these support packages for O/R (Object Relational) mappers comply with
Spring's generic transaction and DAO exception hierarchies. There are usually two
integration styles: either using Spring's DAO 'templates' or coding DAOs against plain
Hibernate/JDO/TopLink/etc APIs. In both cases, DAOs can be configured through
Dependency Injection and participate in Spring's resource and transaction management.
Spring adds significant support when using the O/R mapping layer of your choice to
create data access applications. First of all, you should know that once you started using
Spring's support for O/R mapping, you don't have to go all the way. No matter to what
extent, you're invited to review and leverage the Spring approach, before deciding to take
the effort and risk of building a similar infrastructure in-house. Much of the O/R mapping
support, no matter what technology you're using may be used in a library style, as
everything is designed as a set of reusable JavaBeans. Usage inside a Spring IoC
container does provide additional benefits in terms of ease of configuration and
deployment; as such, most examples in this section show configuration inside a Spring
container.
49
Some of the benefits of using the Spring Framework to create your ORM DAOs include:
• Ease of testing. Spring's IoC approach makes it easy to swap the implementations
and config locations of Hibernate SessionFactory instances, JDBC
DataSource instances, transaction managers, and mappes object
implementations (if needed). This makes it much easier to isolate and test each
piece of persistence-related code in isolation.
• Common data access exceptions. Spring can wrap exceptions from your O/R
mapping tool of choice, converting them from proprietary (potentially checked)
exceptions to a common runtime DataAccessException hierarchy. This allows
you to handle most persistence exceptions, which are non-recoverable, only in the
appropriate layers, without annoying boilerplate catches/throws, and exception
declarations. You can still trap and handle exceptions anywhere you need to.
Remember that JDBC exceptions (including DB specific dialects) are also
converted to the same hierarchy, meaning that you can perform some operations
with JDBC within a consistent programming model.
• General resource management. Spring application contexts can handle the
location and configuration of Hibernate SessionFactory instances, JDBC
DataSource instances, iBATIS SQL Maps configuration objects, and other
related resources. This makes these values easy to manage and change. Spring
offers efficient, easy and safe handling of persistence resources. For example:
related code using Hibernate generally needs to use the same Hibernate Session
for efficiency and proper transaction handling. Spring makes it easy to
transparently create and bind a Session to the current thread, either by using an
explicit 'template' wrapper class at the Java code level or by exposing a current
Session through the Hibernate SessionFactory (for DAOs based on plain
Hibernate API). Thus Spring solves many of the issues that repeatedly arise from
typical Hibernate usage, for any transaction environment (local or JTA).
• Integrated transaction management. Spring allows you to wrap your O/R
mapping code with either a declarative, AOP style method interceptor, or an
explicit 'template' wrapper class at the Java code level. In either case, transaction
semantics are handled for you, and proper transaction handling (rollback, etc) in
case of exceptions is taken care of. As discussed below, you also get the benefit of
being able to use and swap various transaction managers, without your
Hibernate/JDO related code being affected: for example, between local
transactions and JTA, with the same full services (such as declarative
transactions) available in both scenarios. As an additional benefit, JDBC-related
code can fully integrate transactionally with the code you use to do O/R mapping.
This is useful for data access that's not suitable for O/R mapping, such as batch
processing or streaming of BLOBs, which still needs to share common
transactions with ORM operations.
The PetClinic sample in the Spring distribution offers alternative DAO implementations
and application context configurations for JDBC, Hibernate, Oracle TopLink, and JPA.
50
PetClinic can therefore serve as working sample app that illustrates the use of Hibernate,
TopLink and JPA in a Spring web application. It also leverages declarative transaction
demarcation with different transaction strategies.
The JPetStore sample illustrates the use of iBATIS SQL Maps in a Spring environment.
It also features two web tier versions: one based on Spring Web MVC, one based on
Struts.
Beyond the samples shipped with Spring, there are a variety of Spring-based O/R
mapping samples provided by specific vendors: for example, the JDO implementations
JPOX (http://www.jpox.org/) and Kodo (http://www.bea.com/kodo/).
12.2. Hibernate
We will start with a coverage of Hibernate 3 in a Spring environment, using it to
demonstrate the approach that Spring takes towards integrating O/R mappers. This
section will cover many issues in detail and show different variations of DAO
implementations and transaction demarcation. Most of these patterns can be directly
translated to all other supported ORM tools. The following sections in this chapter will
then cover the other ORM technologies, showing briefer examples there.
Note: As of Spring 2.5, Spring requires Hibernate 3.1 or higher. Neither Hibernate 2.1
nor Hibernate 3.0 are supported anymore.
Typical business applications are often cluttered with repetitive resource management
code. Many projects try to invent their own solutions for this issue, sometimes sacrificing
proper handling of failures for programming convenience. Spring advocates strikingly
simple solutions for proper resource handling, namely IoC via templating; for example
infrastructure classes with callback interfaces, or applying AOP interceptors. The
infrastructure cares for proper resource handling, and for appropriate conversion of
specific API exceptions to an unchecked infrastructure exception hierarchy. Spring
introduces a DAO exception hierarchy, applicable to any data access strategy. For direct
JDBC, the JdbcTemplate class mentioned in a previous section cares for connection
handling, and for proper conversion of SQLException to the
DataAccessException hierarchy, including translation of database-specific SQL
51
error codes to meaningful exception classes. It supports both JTA and JDBC transactions,
via respective Spring transaction managers.
To avoid tying application objects to hard-coded resource lookups, Spring allows you to
define resources such as a JDBC DataSource or a Hibernate SessionFactory as
beans in the Spring container. Application objects that need to access resources just
receive references to such pre-defined instances via bean references (the DAO definition
in the next section illustrates this). The following excerpt from an XML application
context definition shows how to set up a JDBC DataSource and a Hibernate
SessionFactory on top of it:
<beans>
52
<bean id="mySessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="myDataSource"/>
<property name="mappingResources">
<list>
<value>product.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<value>
hibernate.dialect=org.hibernate.dialect.HSQLDialect
</value>
</property>
</bean>
</beans>
<beans>
</beans>
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 bean
reference from a Spring IoC container - via a simple setSessionFactory(..) bean
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.
53
<beans>
</beans>
public class ProductDaoImpl implements ProductDao {
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.
54
}
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 setSessionFactory(..)
method for receiving a SessionFactory, and getSessionFactory() and
getHibernateTemplate()for use by subclasses. In combination, this allows for
very simple DAO implementations for typical requirements:
55
public Collection loadProductsByCategory(String category) throws
DataAccessException, MyException {
Session session = getSession(false);
try {
Query query = session.createQuery("from test.Product product where
product.category=?");
query.setString(0, category);
List result = query.list();
if (result == null) {
throw new MyException("No search results.");
}
return result;
}
catch (HibernateException ex) {
throw convertHibernateAccessException(ex);
}
}
}
The advantage of such direct Hibernate access code is that it allows any checked
application exception to be thrown within the data access code; contrast this to the
HibernateTemplate class which is restricted to throwing only unchecked exceptions
within the callback. Note that you can often defer the corresponding checks and the
throwing of application exceptions to after the callback, which still allows working with
HibernateTemplate. In general, the HibernateTemplate class' convenience
methods are simpler and more convenient for many scenarios.
56
.setParameter(0, category)
.list();
}
}
This style is very similar to what you will find in the Hibernate reference documentation
and examples, except for holding the SessionFactory in an instance variable. We
strongly recommend such an instance-based setup over the old-school static
HibernateUtil class from Hibernate's CaveatEmptor sample application. (In general,
do not keep any resources in static variables unless absolutely necessary.)
The above DAO follows the Dependency Injection pattern: it fits nicely into a Spring IoC
container, just like it would if coded against Spring's HibernateTemplate. Of
course, such a DAO can also be set up in plain Java (for example, in unit tests): simply
instantiate it and call setSessionFactory(..) with the desired factory reference.
As a Spring bean definition, it would look as follows:
<beans>
</beans>
The main advantage of this DAO style is that it depends on Hibernate API only; no
import of any Spring class is required. This is of course appealing from a non-
invasiveness perspective, and will no doubt feel more natural to Hibernate developers.
57
strategy, returning the current Spring-managed transactional Session even with
HibernateTransactionManager. Of course, the standard behavior of that method
remains: returning the current Session associated with the ongoing JTA transaction, if
any (no matter whether driven by Spring's JtaTransactionManager, by EJB CMT,
or by JTA).
In summary: DAOs can be implemented based on the plain Hibernate 3 API, while still
being able to participate in Spring-managed transactions.
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 bean reference via a setTransactionManager(..)
method - 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.
<beans>
<bean id="myTxManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="mySessionFactory"/>
</bean>
</beans>
public class ProductServiceImpl implements ProductService {
58
public void setProductDao(ProductDao productDao) {
this.productDao = productDao;
}
Alternatively, one can use Spring's declarative transaction support, which essentially
enables you to replace explicit transaction demarcation API calls in your Java code with
an AOP transaction interceptor configured in a Spring container. This allows you to keep
business services free of repetitive transaction demarcation code, and allows you to focus
on adding business logic which is where the real value of your application lies.
Furthermore, transaction semantics like propagation behavior and isolation level can be
changed in a configuration file and do not affect the business service implementations.
<beans>
<bean id="myTxManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="mySessionFactory"/>
</bean>
<bean id="myProductService"
class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces" value="product.ProductService"/>
<property name="target">
<bean class="product.DefaultProductService">
<property name="productDao" ref="myProductDao"/>
</bean>
</property>
<property name="interceptorNames">
<list>
<value>myTxInterceptor</value> <!-- the transaction interceptor (configured
elsewhere) -->
59
</list>
</property>
</bean>
</beans>
public class ProductServiceImpl implements ProductService {
The following higher level approach to declarative transactions doesn't use the
ProxyFactoryBean, and as such may be easier to use if you have a large number of
service objects that you wish to make transactional.
Note
You are strongly encouraged to read the section entitled Section 9.5, “Declarative transaction
management” if you have not done so already prior to continuing.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
60
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
<bean id="myTxManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="mySessionFactory"/>
</bean>
<aop:config>
<aop:pointcut id="productServiceMethods" expression="execution(*
product.ProductService.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="productServiceMethods"/>
</aop:config>
</beans>
61
configuration. Simply replace the Hibernate transaction manager with Spring's JTA
transaction implementation. Both transaction demarcation and data access code will work
without changes, as they just use the generic transaction management APIs.
For distributed transactions across multiple Hibernate session factories, simply combine
JtaTransactionManager as a transaction strategy with multiple
LocalSessionFactoryBean definitions. Each of your DAOs then gets one specific
SessionFactory reference passed into its corresponding bean property. If all
underlying JDBC data sources are transactional container ones, a business service can
demarcate transactions across any number of DAOs and any number of session factories
without special regard, as long as it is using JtaTransactionManager as the
strategy.
<beans>
<bean id="mySessionFactory1"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="myDataSource1"/>
<property name="mappingResources">
<list>
<value>product.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<value>
hibernate.dialect=org.hibernate.dialect.MySQLDialect
hibernate.show_sql=true
</value>
</property>
</bean>
<bean id="mySessionFactory2"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="myDataSource2"/>
<property name="mappingResources">
<list>
<value>inventory.hbm.xml</value>
</list>
62
</property>
<property name="hibernateProperties">
<value>
hibernate.dialect=org.hibernate.dialect.OracleDialect
</value>
</property>
</bean>
<bean id="myTxManager"
class="org.springframework.transaction.jta.JtaTransactionManager"/>
<!-- this shows the Spring 1.x style of declarative transaction configuration -->
<!-- it is totally supported, 100% legal in Spring 2.x, but see also above for the
sleeker, Spring 2.0 style -->
<bean id="myProductService"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean
">
<property name="transactionManager" ref="myTxManager"/>
<property name="target">
<bean class="product.ProductServiceImpl">
<property name="productDao" ref="myProductDao"/>
<property name="inventoryDao" ref="myInventoryDao"/>
</bean>
</property>
<property name="transactionAttributes">
<props>
<prop key="increasePrice*">PROPAGATION_REQUIRED</prop>
<prop key="someOtherBusinessMethod">PROPAGATION_REQUIRES_NEW</prop>
<prop key="*">PROPAGATION_SUPPORTS,readOnly</prop>
</props>
</property>
</bean>
</beans>
63
HibernateTransactionManager can export the JDBC Connection used by
Hibernate to plain JDBC access code, for a specific DataSource. This allows for high-
level transaction demarcation with mixed Hibernate/JDBC data access completely
without JTA, as long as you are just accessing one database!
HibernateTransactionManager will automatically expose the Hibernate
transaction as JDBC transaction if the passed-in SessionFactory has been set up
with a DataSource (through the "dataSource" property of the
LocalSessionFactoryBean class). Alternatively, the DataSource that the
transactions are supposed to be exposed for can also be specified explicitly, through the
"dataSource" property of the HibernateTransactionManager class.
64