Κυριακή, 17 Απριλίου 2011

Future of web applications

Wondering about the future of web applications.... Seems we have entered the JavaScript era for good. And a shift in web applications development is apparent. Technologies and architectures such as Ajax, REST, JSON, GWT, OAuth, client side state, jQuery, node.js (!), etc are making us think about web applications in a different way. Is the browser based fat clients the clean approach to building RIAs? Wondering whether this model can and should replace the server side programming. I guess as usual, it depends on the problem...

Κυριακή, 26 Απριλίου 2009

How to save JSF state across web flow view states

Spring-faces provides great integration between Spring Web Flow 2 and JSF. Each view-state in web flow renders a JSF view, a stateful tree of JSF components. When exiting a view-state (e.g. when transitioning from one view-state to another) the state of the JSF component tree is naturally lost. There are times though when you want to transition back to that view-state and see the view exactly the way it was last time. For example you might want to transition to a view-state where you search for and select a value and then you want to go back to the originating view-state and see it exactly the way you left it.

A nice way to achieve this with spring-faces is to store the JSF component tree state in the flow scope when leaving the view-state. Then, when entering it again, you may restore it and clean the flow scope. The best place to put this logic is in a FlowExecutionListener. Saving the JSF view state must happen before the transition and restoring must happen on entry of the view-state.

The fundamental questions are:
1) where can you find the JSF state to save?
2) where should you put the JSF state when you restore?

Well, the answer to both questions is the same. When you restore the JSF state you need to put it at the same place that you find it when saving it. That is in the view scope under the key "flowSerializedViewState". So right before the transition you need to copy the contents of viewState.flowSerializedViewState to flowScope.myKey and on entry of the view-state you need to copy the contents of flowScope.myKey to viewState.flowSerializedViewState. Web flow's JSF StateManager will actually restore the JSF component tree using the state you injected into the view scope.

That's it. Remember that this is actually a hack of the Spring-faces state manager, so it comes with no guarantees of later versions compatibility. But it's a neat way to save and restore the JSF view state accross Spring web flow view-states. This works with the current latest version of SWF (2.0.7).

Παρασκευή, 2 Μαΐου 2008

Spring Web Flow 2.0.0 released

Spring Web Flow 2.0.0 production release was out 3 days ago. This one is quite of a milestone release. From my point of view, the most important change in this release is the fact that SWF now includes the responsibility of view rendering instead of pushing off this task to its caller (usually Spring MVC). See the vision of SWF 2 here. This important change enables a wealth of new features, such as most importantly the introduction of a new module called spring-faces.

Many other interesting features are there too:
  • New simplified flow definition syntax,
  • Spring Javascript module introducing support for Ajax views,
  • A library of JSF components (part of spring-faces),
  • FormAction is replaced by declarative binding and validation to model
  • Popup view-states,
  • Flow managed persistence contexts (session-per-conversation)
  • Flow definition inheritance,
  • View scope,
  • History polices,
  • Integration with security,
  • etc

Τρίτη, 29 Απριλίου 2008

Integrating CMT EJB, Spring, and Hibernate

/* using Spring 2.0.8, Hibernate 3.2.5 */

Integrating Spring and Hibernate is quite well documented in the Spring reference and other books. However, there is a special case which involves combining a CMT (Container Managed Transaction) EJB, Spring and Hibernate. This has been a little hard for me to figure out, so I would like to share the configuration that I found most appropriate in this scenario.

The above mentioned combination of technologies is mostly useful in Message Driven Beans (MDB) using Hibernate via Spring to persist something in the database upon reception of a message. Usually, I prefer configuring MDBs with CMT because the container dequeues the message under the covers before control is handed over to our MDB, and I would like this dequeue operation to be part of the transaction. Using CMT is the most straightforward configuration that comes to mind. Another option, which achieves the same results but without including the dequeue operation in the actual JTA transaction is described in this article.

Since we are using CMT, we are not going to use any transaction management at the Spring level. We must not include a PlatformTransactionManager in the spring context. We are letting the container do all transaction demarcation for us.

At this point, I have set the MDB with CMT and I have added a LocalSessionFactoryBean to the Spring context, as you can see in the following listing:

<jee:jndi-lookup id="dataSource" jndi-name="jdbc/myDS" resource-ref="true"/>

<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource">
<property name="mappingResources" ref="...">
<property name="hibernateProperties">
<props>
...hibernate properties unrelated to transactions, sessions, connections...
</props>
</property>
</bean>



The hibernate operations are performed using Spring's HibernateTemplate. As long as we have configured the application server's JNDI data source to be XA, with no other configuration, all Hibernate operations are part of the same global transaction. The container ensures this by handing out an XA enabled data source to Spring, which hands it out to Hibernate. So there is no problem of transaction atomicity. There is another problem however: Session propagation. Session propagation refers to using the same Hibernate session throughout the logical unit of work. With the previous configuration, a Hibernate Session is opened, flushed and closed (automatically by Spring) for each hibernate operation. Although this actually works, it is not very efficient. This is referred to as the "session-per-operation" anti pattern. Most annoyingly, lazy loading of persistent objects outside of the hibernate operation (HibernateTempate.doInHibernate method callback) will throw an Exception since the session is closed immediately after the operation. So, what can we do to fix this?

To make a long story short, the configuration I have found that works best is the following:

<jee:jndi-lookup id="dataSource" jndi-name="jdbc/myDS" resource-ref="true"/>

<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="mappingResources" ref="..."/>
<property name="hibernateProperties">
<props>
<prop key="hibernate.transaction.factory_class">org.hibernate.transaction.CMTTransactionFactory</prop>
<prop key="hibernate.transaction.manager_lookup_class">...(depends on you application server, check documentation)...</prop>
<prop key="hibernate.connection.release_mode">auto</prop>
...hibernate properties unrelated to transactions, sessions, connections...
</props>
</property>
</bean>

The main thing to notice is that we need to tell the hibernate SessionFactory how to get access to the JTA transaction manager. This is achieved with the property manager_lookup_class. This lets Spring enable it's session propagation feature, and therefore keep the same hibernate session throughout the entire transaction. Session propagation is enabled by Spring if either transaction demarcation is Spring driven (which in this case is not) or a JTA transaction manager is configured on the Hibernate SessionFactory. As soon as Spring detects a transaction manager configured on the SessionFactory it binds the Session to the current transaction. Also, it registers a callback so that flushing and closing the session occurs automatically at the end of the transaction instead of after each operation. In the CMT case, the container is the one who commits the transaction and calls back the Spring callback.

Second, we need to let hibernate know that we are in a CMT environment. This is done with the factory_class property.

Additionally, since we are using JTA and XA enabled data sources (the transaction is by definition distributed since it involved dequeuing from a JMS queue and writing to a database) we would like to use aggressive connection release strategy as described in Hibernate documentation chapter 11.5. The release_mode property is set to "auto" to achieve this. To explain this point a little further, Spring by default sets the release mode for Hibernate SessionFactory to on_close. That means keeping the connection until the session is closed. Setting the Hibernate property release_mode to auto overrides the Spring setting. The possible values are on_close, after_statement, after_transaction and auto. The value we really want is after_statement, so why set it to auto? That's because if we set it to after_statement Hibernate (SettingsFactory.buildSettings) asks the ConnectionProvider whether it supports aggressive connection release. ConnectionProvider is set to LocalDataSourceConnectionProvider by Spring and returns false. If we set release_mode to auto, ConnectionProvider is not consulted, but instead the setting is taken from the transaction factory (which is set to CMTTransactionFactory in our case), which returns after_statement.

This setup achieves the session-per-request pattern for CMT beans.

Additional information on Spring and Hibernate transaction management

You may wonder how would session propagation be performed if we did not have Spring. Hibernate offers one simple method: SessionFactory.getCurrentSession(). You are supposed to call this method whenever you want to access a Hibernate Session instead of calling openSession. The first time you call this method, a new Session is opened and binded to the transaction (either JTA or not). Each successive time you call the method, it returns the same session. Also notice that without this method you would normally have to flush and close the session programatically. With this method though, the session is auto flushed and auto closed when the transaction ends.

As mentioned above Spring offers the same features as SessionFactory.getCurrentSession() when either transaction demarcation is Spring driven or a JTA transaction manager is configured on the Hibernate SessionFactory. When using HibernateTemplate to perform operations with Hibernate, Spring uses its own session management with SessionFactoryUtils. SessionFactoryUtils also offers automatic flushing and closing of the session when the transaction ends without any additional Spring or Hibernate properties needed. So you don't need to programmatically flush and close the session at the end of the transaction. Note that when the above Spring features are enabled, even if you use getCurrentSession instead of HibernateTemplate, Spring overrides this method to use its own session management (this is what the exposeTransactionAwareSessionFactory parameter does).