How to use MatchMode in your JPA/Hibernate Restrictions & Criteria queries

Back in July I blogged about how to do AND/OR type SQL queries using Hibernate AND/OR JPA using disjunctions. If you looked at the example code you will have seen that I was appending "%" as the wildcard operator in my Restrictions.

Since then I've used Restrictions a couple more times and wondered if there was a better way of specifying them other than string concatenation.

Well there is and it's with the use of the MatchMode class.

Rather than this code:

import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.criterion.Restrictions;
 
Criteria criteria = session.createCriteria(Product.class);
criteria.add(
  Restrictions.disjunction()
    .add(Restrictions.ilike("code", codeOrName + "%"))
    .add(Restrictions.ilike("name", "%" + codeOrName + "%"))
);
return criteria.list();
You can now write:
import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.criterion.Restrictions;
 
Criteria criteria = session.createCriteria(Product.class);
criteria.add(
  Restrictions.disjunction()
    .add(Restrictions.ilike("code", codeOrName, MatchMode.START))
    .add(Restrictions.ilike("name", codeOrName, MatchMode.ANYWHERE))
);
return criteria.list();

Accessing & iterating over a Java Map in a JSP page with JSTL

When you are coding JSP pages using JSTL one thing you use a lot is the <c:foreach> tag. This tag a great for iterating over Lists or Sets but what do you do when you want to display the contents of a Map?

Firstly you need to decide how you are going to use the Map. Do you want to access a 'value' stored within the Map based on a known key or iterate over the Map displaying both key and value?

Access a Map based on a 'key'

This one is pretty straight forward you just need to know the JSTL syntax:

${aMapFullOfKeysAndValues[yourKnownKey]}
Two key points:
  • The key is an existing JSTL variable or a quoted string
  • You use square brackets at the end of the Map name
Iterate over a Map pulling out the 'key' & 'value'

This is a little more complex, note the name of the variable that is filled on each pass through the Map ('entry'):

    ${entry.key} - ${entry.value}
Four key points:
  • The name of the Map is placed as the 'items' attribute of the forEach
  • To access the 'key' object use ${entry.key}
  • To access the 'value' object use ${entry.value}
  • If either the key or value is a complex object, simply walk into it: ${entry.value.surname}
Hopefully that has demystified it a little, please post a comment if you found this post useful or I've missed something out!

Spring Autowiring & Component Scanning Problems - Part 6: The Remedy

Part 5 can be found here

So what can you do about root context beans not being wired correctly?

One solution is to ensure that all your root context beans have their autowiring specified via XML, either with explicit elements or autowire="byType" or autowire="byName" XML attributes, but this is a bit of a backward step considering how annotation centric Spring is becoming.

You could enable component scanning (via the XML element) and go through the beans marking them with the @Component family of annotations so that the @Autowired statements are picked up. You will also need to remove the XML-based bean definitions from the context files otherwise you will end up with two conflicting beans - one loaded due to the XML declaration and another loaded due to component scanning.

Or you could switch on 'annotation awareness' by adding a XML element to your root application context files. In fact you only need to add it to one of the root context files as all the beans are loaded into the same context and looking for autowired annotations only happens once all the beans are loaded into the context.

Or you could do all of the above but then you might be creating new problems for yourself... ;-)

Spring Autowiring & Component Scanning Problems - Part 5: The Cause

Part 4 can be found here

It's not clearly stated in the Spring documentation but the auto-wiring stage for DispatcherServlets only scan through the beans within it's specific application context searching for autowiring annotations (@Autowired, @Qualifier, etc.), it does not venture into the root application context to wire those beans.

It sometimes appears that it does cross that root context boundary if you have root bean classes annotated with one of the @Component family and you enable your web application's component scanning to include that package. What happens is that the bean is loaded into the root application context and then an overwritten version is loaded into the WebApplicationContext. This overlaid version is then auto-wired as it lives inside the WebApplicationContext.

Part 6 can be found here

Spring Autowiring & Component Scanning Problems - Part 4: Application Contexts

Part 3 can be found here

Spring loads beans into application contexts. Any beans declared in XML files or any annotated classes found via component scanning are placed into a suitable application context - either the root application context or one specific to the web application that the bean is declared in.

Any beans declared (or scanned for) which are not DispatcherServlet related (i.e. not -servlet.xml files) are placed into one big root application context bucket, the support for separate XML application context files is purely a convenience for you to manage the logical separation of the beans.

Each DispatcherServlet gets it's own WebApplicationContext which inherits all the beans from the root application context, overlaying all the beans defined within it's web application scope (i.e. any beans within -servlet.xml). Once all the DispatcherServlet's beans are loaded it will attempt to autowire them together and this is where the potential problems start.

Part 5 can be found here

Spring Autowiring & Component Scanning Problems - Part 3: Autowiring

Part 2 can be found here

Having a load of beans instantiated in an application context is one thing, having them wired together so that they know about each other is another. Wiring can be done either using XML or via the @Autowired annotation. The annotations on their own don't cause Spring to wire the beans, you need to turn on annotation support for Spring to find them:

<context:annotation-config/>
When added to an application context XML file it instructs Spring to look through all the loaded beans in the relevant application context for annotations like @Autowired, @Qualifier & @Required. In a reasonably mature Spring application you could have the beans being wired together in a number of ways:
  • Explicit <property> XML elements referencing other beans
  • The addition of autowire="byType" or autowire="byName" XML attributes
  • @Autowired annotations inside normal classes declared as beans in XML
  • @Autowired annotations inside @Component-based classes
Note: The <context:component-scan> element also implicitly defines the <context:annotation-config> autowiring element as well - after all if you are scanning for annotated @Component classes you want the embedded @Autowired annotations to be scanned for as well.

Part 4 can be found here

Spring Autowiring & Component Scanning Problems - Part 2: Component Scanning

Part 1 can be found here

Instead of adding explicit beans to your XML files, Spring 2.5 introduced the @Component annotation family (@Service, @Controller, @Repository – all children of the @Component parent annotation). Simply add these object-level annotations to your class definitions to mark what type of Spring bean they are. Then add the following XML snippet to the application context XML file to tell Spring where to look:

<context:component-scan base-package="com.andrewbeacock"/>
Spring now scans through the whole classpath for the specified package (and sub-packages) looking for @Component-based classes. Any found are created as beans and placed in the application context.

This purely adds the beans to the relevant application context, it doesn't look inside the class for other annotations until it's finished loading all the remaining beans into the context.

Part 3 can be found here

Spring Autowiring & Component Scanning Problems - Part 1: The Problem

Let's set the scene a little: You're a developer on a long-running Spring-based web application. It's a reasonably large application developed before annotations were a twinkle in Spring's eye and so uses XML to declare the beans and wiring. Over time the use of annotations has grown - particularly in the area of annotated controllers - and you've started to add @Autowired annotations rather than explicitly defining the wiring in the XML application context files.

So now you've got a good mix of XML-defined beans and annotated ones, sometimes mixing the two together; a bean is declared in the XML context file but it's wirings are defined using @Autowired statements rather than the usual XML elements.

Everything is working perfectly...

You've never had a problem adding @Autowired annotations to beans until now, but a particular bean's members don't seem to get wired (you get a NullPointerException at runtime) but you don't get a wiring error. This is confusing as you know that the @Autowired annotation has 'required' set to true by default, so it should be throwing a wiring exception during the loading of the context at the very least!

Why is it not wiring correctly? Because Spring is not even seeing the @Autowired annotation! To fully understand the issues at hand we need to wind back a bit and cover some theory.

Part 2 can be found here

Something new for my blog

I'm going to try something new, a multi-post feature which is basically an article I've written for an open source journal but broken up into bite-sized pieces and posted over a couple of weeks (or so).

Please comment if you like it, find it annoying, my content is completely wrong, etc. I'd like to hear from you.

My series is on "Spring Autowiring & Component Scanning Problems"

Have more than one gmail account?

Not sure if you are aware of this but Google have added a rather funky dropdown account selector to a number of their applications, more details are here:

Access two Gmail accounts at once in the same browser

A damn fine invention if you ask me!

How to do AND/OR type SQL queries using Hibernate AND/OR JPA using disjunctions

If you have been using Hibernate or JPA for a while you will know that the Criteria and Restrictions classes are very handy for querying the database without writing any SQL code and without worrying about the real column names (these are all captured in the annotations that you have applied to the domain objects).

This is fine when you want to search for objects (rows) which are a combination of columns such as forename = "Andrew" AND surname = "Beacock" but what if you want to search for all people who either have a forename of Andrew and/or a surname of Beacock?

This is where a "disjunction" comes in. This is one of the types hanging off the Restrictions class and deals with AND/OR situations. The code below is looking through the 'products' table for any product that has a code or name starting with the text supplied:

import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.criterion.Restrictions;
 
Criteria criteria = session.createCriteria(Product.class);
criteria.add(
  Restrictions.disjunction()
    .add(Restrictions.ilike("code", codeOrName + "%"))
    .add(Restrictions.ilike("name", codeOrName + "%"))
);
return criteria.list();

You can obviously add as many additional Restrictions as you like to the disjunction to make it as simple or complex as you like...

iPhone version of the excellent Password Composer

I've been using the excellent Password Composer Greasemonkey script for Firefox for over 2 years now - it's a great way to ensure that your master password isn't spread around the web yet never gets in the way of accessing a site.

My collegue Andy Kayley recently pointed out that there is an iPhone version available so that you can easily access your Password Composer encrypted passwords whilst on the move!  It's written by Jon Parise and not only does he include a link to his version but also goes into excellent detail on how he developed the iPhone application!

Now I just need to get myself an iPhone... ;)

googlemail is going, gmail returns (if you're in the UK)

This might be old news now but Google now have the ability to use 'gmail.com' for UK people rather than the awkward 'googlemail.com':

Why did you change the name from Google Mail to Gmail?

A little more than a year after Gmail first launched, Google changed the name of its webmail service in the United Kingdom to "Google Mail" due to negotiations over a trademark dispute. We have reached a settlement, so we are happily changing the name back to Gmail, and offering @gmail.com addresses to all Google Mail users in the UK. Plus, it's shorter and easier to type this way :)
There's more information about it here: Google Mail is becoming Gmail in the UK

Technorati Tags: , ,

Firebug is a jQuery console test/debugging tool too!

I thought everyone knew this, but after a chat with a couple of colleagues this week it seems that most don't know that...

...if you use Firebug (in Firefox) on a jQuery-enabled website, Firebug's console can handle jQuery selectors and other jQuery magic.

To see for yourself, make sure you have Firebug installed, then visit the jQuery home page. Ensure that the console is enabled and type the following and hit return:

$('#jq-content').fadeOut()
You should hopefully see most of jQuery's home page gently fade out!

This feature is invaluable when investigating & debugging jQuery javascript code, make sure you install Firebug into Firefox today!

Technorati Tags: , , ,

jQuery tip: Selecting ids with periods in them (dots/'.')

I was messing around with jQuery today combined with a Spring form-backed bean and was finding that my jQuery was failing to work. The id of the input field bound to my Spring form was person.id.

Trying to get the value entered into the input box was failing, this is what I was trying:

$('#person.id').val();
The problem here is the period - '.' - jQuery see these as CSS notation and so fails to find an element with that id, what you need to do is add two backslashes ('\\') before the period to escape it, like this:
$('#person\\.id').val();
See the jQuery FAQ for more details.

Technorati Tags: , ,

Great tip regarding annotated Spring form validation & BindingResult

Found an interesting little gotcha at work last week, I was adding form validation to an annotated Spring controller, creating a custom Validator to do the work and wiring it in to the controller's method signature with the use of the BindingResult parameter (I just tacked it on the end of my existing parameters):

@RequestMapping(method=RequestMethod.POST, params="action=person")
public String createPerson(@ModelAttribute("person") PersonForm person, ModelMap model, BindingResult result) {
    // code goes here...
}
This resulted in a slightly odd error message:
java.lang.IllegalStateException: Errors/BindingResult argument 
declared without preceding model attribute. Check your handler method 
signature!
I was a little confused by this message, it was indicating that I didn't have the form's model attribute declared before the BindingResult but I certainly have. After some google searching for this error message I found a website created by a colleague of mine (Mark Lishman) which had just the answer that I needed:
The BindingResult parameter must be positioned directly after the corresponding model argument that is being validated.
Taken from the information tip box on the Level Up Spring MVC Form Validation page.
So basically it meant that my controller method should have been this:
@RequestMapping(method=RequestMethod.POST, params="action=person")
public String createPerson(@ModelAttribute("person") PersonForm person, BindingResult result, ModelMap model) {
    // code goes here...
}
Level Up is an excellent resource for people starting out with Spring, Hibernate & Oracle, check it all out at the Level Up website.

Technorati Tags: , , , , ,

Summary of March's Manchester Open Source Central User Group Meeting

I really enjoyed last night's Open Source Central user group meeting in Manchester. Both speakers were excellent and there were a lot of good ideas to take away.  Here is my summary of the evening:

"Spring BlazeDS Integration" by Rick Evans


He started with an overview of why build web applications with Flex & Flash: rich internet applications which look like a desktop application rather than a bunch of web pages. He then suggested that Flex & Flash applications client applications could be powered by a Spring server backend by using BlazeDS.

Flex is a framework for building rich internet applications. You get the same looking application regardless of operating system or browser which can't be said for regular web-based applications. Flex applications can be deployed into the standard flash player embedded in the browser or as a desktop application via Adobe AIR.  You write Flex applications in ActionScript which is an OO language enabling a simple transition from languages such as Java or C#.

BlazeDS is an open source project from Adobe offering transparent communication with backend services. This remoting library offers connectivity to:
* RPC services - web service, HTTP service, remote object service
* Messaging - publish/subscribe,collaboration, real time data push
* Service adapters - JMS, Java, custom

BlazeDS is the open source part of Adobe's Livecycle ES application, a commercial offering which costs but provides greater scalability. There is also a completely open source version of Livecycle DS called Granite DS (this is not from Adobe).

Then Rick covered what Spring BlazeDS Integration offers. It reuses your existing Spring service tier, offers Spring configuration for BlazeDS components & let's you use the Spring programming model for your BlazeDS components. It also offers easy integration with other Spring projects including Spring Security & Spring Integration.

BlazeDS allows backend Java objects to be converted into ActionScript objects on the client side without the need for manual translation code.  It uses a proprietary binary wire format over HTTP although you can switch it to XML over HTTP if required - could be useful for debugging?

To open up your Spring services as remote endpoints is simply a matter of adding a @RemotingDestination annotation to your @Service class and then add @RemotingInclude annotations to any methods that you want to expose. Spring BlazeDS Integration offers a Flex namespace that you can use in your application context files, to enable the Flex message broker object add the element (and set any properties that are suitable for your configuration).

After a number of demos and code walk-throughs Rick concluded his talk of where Spring DS Integration was today - version 1.0.2 was released in Feb 2010 and included spring Security 3 support. The next feature release will be 1.5 including BlazeDS 4 integration & support for serialisation Hibernate object to the client tier.

He also mentioned that Skills Matter are holding a London-based Flex on Java Exchange in June 2010 - and it's just £25.

After a word from the sponsors and some details about the next issue of the Open Source Journal - it's growing from around 12 pages to around 50! - it was on to the next talk.

"iSpring MVC - How to implement mobile-friendly applications in Spring Framework with ease" by Jan Machacek

He started by explaining that if you have an existing Spring web application and want to provide an iPhone version you may not want to go down the "pay $99 for Xcode & code on a mac" maybe preferring to reuse your existing Spring backend objects and replace the standard web pages with iPhone-specific versions.

After that a brief tour of Spring web application development was undertaken to ensure that everyone was familiar with how views are rendered (i.e. using InternalResourceViewResolver or UrlBasedViewResolver).

The iPhone comes with a good browser so what we need is some way to have some specific CSS styled to the iPhone and a way to tap into some of the special features of the iPhone browser. So we want to reuse the existing backend but return iPhone-specific pages (views) by using a special view resolver which detects the User-Agent of the browser and then uses an appropriate ViewResolver to return the pages.

Jan then introduced the jQTouch library, a jQuery-powered library which (with the help of some iPhone-styled CSS) makes iPhone web applications look like regular native applications.  It has access to some iPhone specific features such as screen orientation and sideways-sliding screens but not access to the camera, etc.

Jan then spent the rest of the time realtime coding a cooking recipe application (typing whilst standing up and talking always impresses!), writing the UserAgentViewResolver & controllers and then running the application so that any iPhones in the audience could try the application out.

It was noted by an old colleague that the web application really did look like a native app with the sideways scrolling and the styling of the buttons and lists. An excellent talk and with jQTouch you really can turn your 'regular' Spring-based web application into an iPhone application (although you obviously need an internet connection of some description!).

Then it was over the road to the Bowling Green pub for a pint (cheers Cake Solutions!) and a catch-up with some of the other attendees - another excellent OSC user group meeting!


You can find a link to Jan's slides over in his blog post of the evening.

Technorati Tags: , , , , , , ,

Details of the 2nd speaker at the next Open Source Central User Group (Manchester) meeting

I blogged a month ago about the main topic of the next Open Source Central User Group meeting in Manchester.  I recently received details of the second topic so I thought I'd better update you all.

Jan Machacek will be talking about how to turn a regular Spring-based web application into an iPhone app, here's what he's going to do:
I will show you how to take your regular Spring web application and turn it into optimised iPhone web application that feels nearly like a native application with just one Java class and a bit of JavaScript and CSS.
Sounds pretty cool and having worked for a number of years in the mobile industry it's something I'm quite keen to find out about.

Make sure you register for the event which will take place on Wednesday 24th March.

Next Open Source Central User Group (Manchester) meeting is 24th March

The next Open Source Central User Group (Manchester) meeting (formally the North West Spring User Group) is meeting on Wednesday 24th March. It's in the usual place and Rick Evans will be speaking about "Lex And Spring Integration: Introducing Spring BlazeDS Integration".

To ensure you have a seat make sure you register for the event!

Technorati Tags: , ,

How to use Junction if you want Symbolic links in Windows XP

Ever since I started developing using Unix machines I've wanted symbolic links in Windows XP.  A recent pursuit of backup solutions left me really wanting symbolic links so I started the search.  This blog post gave me everything I needed, using a tool from Microsoft's website called junction.

This command line tool created junction points between a symbolic name and a real folder on your hard drive (sorry network drives cannot be linked to).

I downloaded it and placed the junction.exe file in my C:\WINDOWS\system32 directory so it would be on my system path.

Below is my little walk-through of how to use junction.

I created a folder on my desktop called "junction test" and created a folder inside that called "folder":


I created a text file called "README.txt" inside the "folder" directory:


I opened a Windows DOS prompt (cmd) and navigated to the "junction test" folder on my desktop, then I ran the junction command like this:
junction "junction" folder

This gave the following output:
Junction v1.05 - Windows junction creator and reparse point viewer

Copyright (C) 2000-2007 Mark Russinovich

Systems Internals - http://www.sysinternals.com


Created: C:\Documents and Settings\abeacock\Desktop\junction test\junction

Targetted at: C:\Documents and Settings\abeacock\Desktop\junction test\folder

And the folder now looked like this:


If I double-clicked on the "junction" folder this is what I saw:


So as you can see the contents of the "folder" directory is now available in via the "junction" directory as well.  Obviously the junction doesn't need to be next to the folder you want to link too (that would be of little use) but it can be anywhere on your harddrive (I was using it to point into my DropBox sync folder).

WARNING ABOUT JUNCTION

Only the junction tool knows that these folders are actually symbolic links, the rest of the Windows file system thinks they are normal folders. So for example you can simply delete the junctions via Windows and they go in your recycle bin and the folder that it points to stays where it was:

 

But if you then empty your recycle bin it also empties the contents of the folder that this junction was pointing at (which is probably NOT what you wanted to happen!):


So please remember to always use the junction command to create & delete junctions, you can also use it to show you which directories are actually junctions so you know if you should delete it or not, refer to the junction download page for more details.

It's a fantastic tool for Windows XP and very very handy for certain things but please bear in mind the warning above...

Technorati Tags: , , ,

Are your Maven profiles being picked up as 'default'?

We recently noticed that the profile that we had marked as default in our Maven settings.xml file was not being set as the default. Like many examples on the web we had the following XML element set in the appropriate profile:

<profiles>
    <profile>
        <activation>
            <activeByDefault/>
        </activation>
    </profile>
</profiles>
After some searching we found this maven-users mailing list post detailing the solution.

<activeByDefault/> isn't enough to set the value, you need to explicitly set the boolean value to true:
<activeByDefault>true</activeByDefault> 
Once we saved that change in our settings.xml file the profile was picked up as the default.

Technorati Tags: ,

A cool way to assert Lists using JUnit

I found this JUnit tip recently over on Joe Walnes's blog, a rather nifty (and different) way to assert whether two Lists contain the same items:

JUnit/TestNG tip: Diffing Lists

Technorati Tags: , ,