Spring 2.5 is out, and it introduces several new exciting features. One of the most exciting features in the new version is the java configuration, and automatic discovery of spring beans. Well, since the beginning of the Spring framework, wiring components to each other and configuring which class will be injected where was done only using XML. Yes, the people behind spring always said that any format can be used to do the configuration, but you have to write your own classes to implement the format you are going to use. Hence, there was nothing but XML until today.
As of now, you can use the auto-wiring features provided by the new version of spring to put the wiring configurations as annotations in your java code. You will still be using XML, but the amount of XML you need to write will be reduced significantly. Mark Fisher wrote a great article on InfoQ titled What's New in Spring 2.5: Part 1. Looking forward for part 2.
Showing posts with label Spring. Show all posts
Showing posts with label Spring. Show all posts
Tuesday, November 20, 2007
Saturday, November 10, 2007
Logback web configurer for Spring
On thing that should be mentioned about logback is that spring doesn't have a ConfigListener for it like the one it has for log4j (the org.springframework.web.util.Log4jConfigListener class). Well, you can write your own code based on the spring source. Thankfully to Davide Baroncelli, he already did that for us. He had already sent the code to the logback user mailing list. The the thread is available online on Nabble, so that if you would like to view it. He also has an updated version that supports auto reloading for logback configurations. Thanks Davide
Sunday, May 20, 2007
Open Session In View
I was a part of a team that have developed several applications using Struts, Spring and Hibernate together, and one of the problems that have faced us while using Hibernate was the rendering of the view. The problem is that when you retrieve an object 'a' of persistence class 'A' that has an instance 'b' of persistence class 'B', and this relation is lazily loaded, the value of 'b' will be 'null'. This will cause a "LazyInitializationException" while rendering the view (if you need the value of 'b' in the view of course).
A quick and easy solution to that is to set the "lazy" attribute to "false" so that 'b' would be initialized while fetching 'a', but this is not always a good idea. In case of many-to-many relationships, using non-lazy relations might result in loading the entire database into the memory using a great number of "select" statements, which will result to very poor performance, and to massive memory consumption.
Another solution is to open another unit of work in the view, which is really bad for several reasons. First of all, as a design concept, the layers of your application should be loosely coupled, and by doing the previous practice you have coupled the presentation layer with you DB layer, which is bad. Another thing is that this destroys the separation of concerns concept.
The solution to this problem can be done by keeping the hibernate session alive until the view is rendered, and this is what Hibernate introduced as the Open Session In View Design Pattern. Since the Hibernate session will be opened, trying to retrieve 'b' in the view will cause Hibernate to go and fetch it from the DB. In a web application, this can be done through a filter/interceptor.
Spring framework comes with both a filter and an interceptor, so that you don't have to write your own. The problem that might face you, if you're using spring's HibernateTemplate,without doing your own session and transaction management, is that you will not be able to save, edit or delete anything, since both the filter and the interceptor provided by spring set the flush mode of the session to "NONE".
A solution to that, which I've learned from a friend of mine recently is to extend the filter provided by spring, override the getSession method to set a different flush mode, and override the closeSession method to flush the session before closing it. The sample code is shown below:
By using this filter, you will be able to render the view easily, without having to set the "lazy" attribute to "false", or to open a hibernate session in the view, but you have to take care not to change any values of the persistence object in the view, because those changes will be saved to the DB at the end of the request. This is the main reason why the flush mode is set to "NONE" in the original filter and interceptor.
A quick and easy solution to that is to set the "lazy" attribute to "false" so that 'b' would be initialized while fetching 'a', but this is not always a good idea. In case of many-to-many relationships, using non-lazy relations might result in loading the entire database into the memory using a great number of "select" statements, which will result to very poor performance, and to massive memory consumption.
Another solution is to open another unit of work in the view, which is really bad for several reasons. First of all, as a design concept, the layers of your application should be loosely coupled, and by doing the previous practice you have coupled the presentation layer with you DB layer, which is bad. Another thing is that this destroys the separation of concerns concept.
The solution to this problem can be done by keeping the hibernate session alive until the view is rendered, and this is what Hibernate introduced as the Open Session In View Design Pattern. Since the Hibernate session will be opened, trying to retrieve 'b' in the view will cause Hibernate to go and fetch it from the DB. In a web application, this can be done through a filter/interceptor.
Spring framework comes with both a filter and an interceptor, so that you don't have to write your own. The problem that might face you, if you're using spring's HibernateTemplate,without doing your own session and transaction management, is that you will not be able to save, edit or delete anything, since both the filter and the interceptor provided by spring set the flush mode of the session to "NONE".
A solution to that, which I've learned from a friend of mine recently is to extend the filter provided by spring, override the getSession method to set a different flush mode, and override the closeSession method to flush the session before closing it. The sample code is shown below:
| public class HibernateFilter extends OpenSessionInViewFilter { @Override protected Session getSession(SessionFactory sessionFactory) throws DataAccessResourceFailureException { Session session = SessionFactoryUtils.getSession(sessionFactory, true); //set the FlushMode to auto in order to save objects. session.setFlushMode(FlushMode.AUTO); return session; } @Override protected void closeSession(Session session, SessionFactory sessionFactory) { try{ if (session != null && session.isOpen() && session.isConnected()) { try { session.flush(); } catch (HibernateException e) { throw new CleanupFailureDataAccessException("Failed to flush session before close: " + e.getMessage(), e); } catch(Exception e){ } } } finally{ super.closeSession(session, sessionFactory); } } } |
By using this filter, you will be able to render the view easily, without having to set the "lazy" attribute to "false", or to open a hibernate session in the view, but you have to take care not to change any values of the persistence object in the view, because those changes will be saved to the DB at the end of the request. This is the main reason why the flush mode is set to "NONE" in the original filter and interceptor.
Subscribe to:
Posts (Atom)