Automatic dirty checking
Person class has many events.
aPerson.getEvents().add(anEvent);
session.getTransaction().commit();
After loading a Person and an Event, simply modify the collection using the normal collection
methods. There is no explicit call to update() or save(); Hibernate automatically detects that the collection has been modified and needs to be updated. This is called automatic dirty checking. The process of synchronizing the memory state with the database, usually only at the end of a unit of work, is called flushing.
Updating data which is detached
// End of first unit of work
aPerson.getEvents().add(anEvent); // aPerson (and its collection) is detached
// Begin second unit of work
Session session2 = HibernateUtil.getSessionFactory().getCurrentSession();
session2.beginTransaction();
session2.update(aPerson); // Reattachment of aPerson
session2.getTransaction().commit();
Inverse=”true”
Person class has a Set collection of participants
What this means is that Hibernate should take the other side, the Person class, when it needs to
find out information about the link between the two.
For you, and for Java, a bi-directional link is simply a matter of setting the references on both sides correctly. Hibernate, however, does not have enough information to correctly arrange SQL INSERT and UPDATE statements (to avoid constraint violations). Making one side of the association inverse tells Hibernate to consider it a mirror of the other side. That is all that is necessary for Hibernate to resolve any issues that arise when transforming a directional navigation model to a SQL database schema. The rules are straightforward: all bi-directional associations need one side as inverse. In a one-to-many association it has to be the many-side, and in many-to-many association you can select either side
Session-per-request
When a request hits the servlet, a new Hibernate Session is opened through the first call to getCurrentSession() on the SessionFactory. A database transaction is then started. All data access occurs inside a transaction irrespective of whether the data is read or written. Do not use the auto-commit mode in applications. If any problems occurred during processing or rendering, an exception will be thrown and the database transaction rolled back.
protected void doGet(
HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException
{
SimpleDateFormat dateFormatter = new SimpleDateFormat( "dd.MM.yyyy" );
try {
// Begin unit of work
HibernateUtil.getSessionFactory().getCurrentSession().beginTransaction();
// Process request and render page...
// End unit of work
HibernateUtil.getSessionFactory().getCurrentSession().getTransaction().commit();
}
catch (Exception ex) {
}
Open Session In View Pattern
The problem
A common issue in a typical (web-)application is the rendering of the view, after the main logic of the action has been completed, and therefore, the Hibernate Session has already been closed and the database transaction has ended. If you access detached objects that have been loaded in the Session inside your JSP (or any other view rendering mechanism), you might hit an unloaded collection or a proxy that isn't initialized. The exception you get is: LazyInitializationException: Session has been closed (or a very similar message). Of course, this is to be expected, after all you already ended your unit of work.
Solution
The solution, in two-tiered systems, with the action execution, data access through the Session, and the rendering of the view all in the same virtual machine, is to keep the Session open until the view has been rendered. In a three-tier environment the view might be rendered on the presentation virtual machine, not on the service virtual machine with the business and data access layer. Therefore, keeping the Session and transaction open is not an option. In this case you have to send the right "amount" of data to the presentation layer, so a view can be constructed with the Session already closed.
Another great explanation: http://springtips.blogspot.com/2007/07/open-session-in-view.html
How to:
- Implement a servlet Filter
- Use Spring
2. Spring:
http://cchweblog.wordpress.com/2009/10/10/using-opensessioninviewfilter-in-spring-web-application/
Web.xml
hibernateFilter
org.springframework.orm.hibernate3.support.OpenSessionInViewFilter
hibernateFilter
/*
This would take care of closing and opening session.
1. Using Filter
Web.xml
HibernateFilter
my.package.HibernateThreadFilter
HibernateFilter
/*
Servlet Filter Class
public class HibernateSessionRequestFilter implements Filter {
private static Log log = LogFactory.getLog(HibernateSessionRequestFilter.class);
private SessionFactory sf;
public void doFilter(ServletRequest request,
ServletResponse response,
FilterChain chain)
throws IOException, ServletException {
try {
log.debug("Starting a database transaction");
sf.getCurrentSession().beginTransaction();
// Call the next filter (continue request processing)
chain.doFilter(request, response);
// Commit and cleanup
log.debug("Committing the database transaction");
sf.getCurrentSession().getTransaction().commit();
http://heapdump.wordpress.com/2010/04/04/should-i-use-open-session-in-view/
Miscellaneous
- sequence generation
- A org.hibernate.Session represents a single-threaded unit of work
- The org.hibernate.SessionFactory is a thread-safe global object that is instantiated once
- Keep hibernate.cfg.xml and log4j.properties file into the src/main/resources directory
- Switching the configuration option for this mechanism to "thread" allows the context of a current unit of work is bound to the current Java thread that executes the application. When the transaction ends, either through commit or rollback, Hibernate automatically unbinds the org.hibernate.Session from the thread and closes it for you
- Detached: The instance was once associated with a persistence context, but that context was closed, or the instance was serialized to another process.