Wednesday, October 21, 2009

Help!!! What training do you need?

My company, Intertech Inc., is conducting a survey on the training needs of the software development community. Whether you are a current customer or a potential future customer, your input is valuable! We want to understand what technology you and your organization are exploring and what training needs are at the top of your “want list.”

In addition to influencing our next course offerings, let me give you another reason to fill out the survey. If you complete the survey and provide Intertech with your email address at the end of the survey, Intertech will send you a coupon for $250 off your next Intertech class (valid for public classes held in 2010)! Its simple and takes about 10 minutes to complete. Just click on the survey link here - 2010 Intertech Course Planning Survey

Monday, October 19, 2009

Interest in Noop?

Have you heard of Noop yet? Noop (see project page here) is a new programming language developed by Google engineers (although not sponsored directly by Google) that is expected to run on the Java Virtual Machine. Why a new program language? According to the project Web site, the purpose of Noop is "encouraging what we believe to be good coding practices and discouraging the worst offenses."

Fans of Spring and the importance of testing (especially unit testing) will note the first two goals of the new language are to build dependency injection and testability right into the language versus having to use 3rd party libraries to bring DI and testing into application environments. Not included in the language (supposedly to make things clearer, simpler, and easier to maintain), among other things are statics, primitive types, and subclassing (implementation inheritance).

To find out more about Noop join their mailing list at noop@googlegroups.com. Also, a short article on Noop can be found on Application Development Trends website here.

Sunday, October 11, 2009

Hibernate’s Smart Automatic Dirty Check

I am one lucky guy. As an instructor, my job begins anew each week. Each week, I face a new group of people trying to learn a technology or skill. People have asked "don't you get bored teaching." How could I? Each week the topic changes and the needs of my students change. And when I am not teaching, I am working to understand new technologies and how/when to put it into courseware.


But perhaps what makes my job the most enjoyable is when I have a group of students that are really engaging and come up with questions that make me stop and think. In other words, they challenge me to improve my own skills/knowledge on a topic that I think I already know pretty well. This week, I was teaching Hibernate and had just one of those questions from one of my students, Josephine.


We were exploring Hibernate's automatic dirty checking. As those familiar with Hibernate have learned, Hibernate knows persistent objects and tracks state change to those objects. No explicit call to save (or update) a persistent object is necessary. Just committing the transaction causes the new state of a persistent object to be synchronized to the database. However, Josephine asked what would happen if the state of an object was changed and then changed back again to the original state in the same transaction? Would Hibernate know that no real change occurred and therefore avoid an SQL call to the database? What's your guess? In fact, the answer surprised me when I tested it out.

To describe the situation with a little more detail, explore the following persistent class and Hibernate mapping file. Nothing real complex about the Contact class or its mapping to a Contact table.

public class Contact {
private Long id = 0L;
private String firstName;
private String lastName;
private Date dateOfBirth;
private boolean married = false;
private int children;
private int age;
//getters and setters and constructors
}

<hibernate-mapping package="com.intertech.domain">
<class name="Contact">
<id name="id">
<generator class="increment" />
</id>
<property name="firstName" column="first_name" not-null="true" />
<property name="lastName" column="last_name" not-null="true" />
<property name="dateOfBirth" column="date_of_birth" type="date" not-null="true" />
<property name="married" />
<property name="children" />
<property name="age" formula="datediff('yy', date_of_birth, curdate())" access="field"/>
</class>
</hibernate-mapping>

Now check out this little bit of test code. In this example, the Contact with an ID of 2 (2 long) has 4 children.

SessionFactory sf = new Configuration().configure().buildSessionFactory();
Session s = sf.openSession();
Transaction t = s.beginTransaction();
Contact c = (Contact) s.load(com.intertech.domain.Contact.class, 2L);
c.setChildren(32);
c.setChildren(4);
t.commit();
s.close();

So, what happens if code updates the number of children to another number (in this case 32) and then returning it to 4? Take a look at the log output (with hibernate.show_sql=true). The answer surprised me!


Hibernate:
select
contact0_.id as id0_0_,
contact0_.first_name as first2_0_0_,
contact0_.last_name as last3_0_0_,
contact0_.date_of_birth as date4_0_0_,
contact0_.married as married0_0_,
contact0_.children as children0_0_,
datediff('yy',contact0_.date_of_birth,curdate()) as formula0_0_ from
Contact contact0_
where
contact0_.id=?

The SQL select is made to load to the Contact, but no update SQL is issued. Hibernate actually checks to see if the state has undergone real modification before issuing an SQL to synchronize the state with the database. Another case of the students teaching the instructor.

Come join me in learning Hibernate in Intertech's Complete Hibernate class. We offer both live and virtual training, and while I may not have all the answers, I'll work hard to find them for you! That's one of the best parts of my job!

Sunday, October 4, 2009

HandlerInterceptors in Spring Web MVC Framework

Last week, I had a wonderful group of people in my class to learn the Spring Framework. In this group, one of my students – Eric - asked me about Spring Web MVC Interceptors. In particular, Eric had a great question about interceptors versus aspect-oriented programming (AOP) provided in Spring. Were they different? Could "normal" Spring AOP be used in place of interceptors and vice versa?

In general, Interceptors, or more precisely HandlerInterceptors, are used to provide cross cutting concerns to a Spring MVC Web application. Here is a quote from Rod Johnson et al's book Java Development with the Spring Framework: "HandlerInterceptors provide the capability to intercept incoming HTTP requests. Interceptors are useful to add additional crosscutting behavior to your web infrastructure, such as security, logging, auditing." Of course, you'll find "crosscutting behavior" the purpose of AOP as well. So indeed, HandlerInterceptors and AOP serve a similar purpose; that is they serve to collect cross cutting concern code usually sprinkled throughout the core concerns of an application. AOP provides a framework for providing cross-cutting concerns throughout all types of applications and application components. HandlerInterceptors are an extension point to a Spring MVC framework, and as such, are a means to provide cross-cutting concerns specific to Web applications. These special cross-cutting concern components also have access to the Web request, response and ModelAndView objects; something normal AOP aspects are not provided directly without some work. If you are unfamiliar with AOP, the Spring API documentation also indicates that HandlerInterceptors work like Servlet Filters.

While there is a rather large amount of documentation and tutorials on intertwining AOP into a Spring application, there is not as much on HandlerInterceptors. So let me use this blog entry to show you how HandlerInterceptors work both in Spring 2 and in Spring 2.5 where annotations (rather than XML) are used to specify the controller and request mapping.

HandlerInterceptors must implement the org.springframework.web.servlet.HandlerInterceptor interface. This interface defines three methods (preHandle, postHandle, and afterCompletion) that get called before a handler is executed (#1 in the diagram below), after a handler is executed but before the view is rendered (#2 below), and after completely handling a Web request and rendering the view(#3 below). These methods allow for all sorts of pre and post processing in the chain of execution associated to each and every Web request.



Here is a simple implementation of the HandlerInterceptor.

package com.intertech.controllers;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.HandlerInterceptor;
public class
TestInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("In pre-processing/n");
return true;
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("done with request/n");
}
@Override
public void postHandle(HttpServletRequest request, HtpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("In post-processing/n");
}
}

Note that the preHandle method returns a boolean. If false is returned, the interceptor indicates the normal execution chain should be aborted. The result is to send an HTTP error or other custom response to the user. The postHandle method is provided a copy of the ModelAndView object. This allows the interceptor to modify the model information or view displayed as normally determined by the Spring MVC controller. Finally, the afterCompletion method serves as a kind of callback after processing the request and rendering the view. This method can and should clean up any resources used by the interceptor.

In Spring 2, interceptors are woven into the Web request execution chain through XML configuration of the handler mapping (note the interceptors property for the SimpleUrlHandlerMapping example below).
<bean id="testInterceptor" class="com.intertech.controllers.TestInterceptor" />
<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="interceptors">
<list>
<ref bean="testInterceptor"/>
</list>
</property>
<property name="mappings">
<props>
<prop key="/addcontact.request">addContactController
</prop>
<prop key="/displayContacts.request">manageContactsController
</prop>
<prop key="/deleteContact.request">manageContactsController
</prop>
</props>
</property>
</bean>
In Spring 2.5 and better, since handler mapping is handled via @RequestMapping annotations, the interceptor must be added to the DefaultAnnotationHandlerMapping. In Spring 2.5 and beyond, the DispatcherServlet enables the DefaultAnnotationHandlerMapping by default, which looks for @RequestMapping annotations on @Controllers. However, the DefaultAnnotationHandlerMapping can still be added to the Spring configuration file and the interceptors added to this handler mapping as shown below.

<bean id="testInterceptor" class="com.intertech.controllers.TestInterceptor" />
<bean id="handlerMapping" class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
<property name="interceptors">
<list><ref bean="testInterceptor"/></list>
</property>
</bean>
Spring already comes with several interceptor adapters (HandlerInterceptorAdapter, LocaleChangeInterceptor, ThemeChangeInterceptor, UserRoleAuthorizationInterceptor, WebContentInterceptor, WebRequestHandlerInterceptorAdapter) so that developers don't have to implement common Web application cross cutting concerns. For example, the UserRoleAuthorizationInterceptor checks the authorization of the current user against the Java EE security roles, as evaluated by HttpServletRequest's isUserInRole method.

To learn more about the Spring Framework or Spring Web MVC, please consider joining me for Intertech's Complete Spring Core or Complete Spring Web class. We offer training at our facility as well as virtually right to your desktop wherever you are.