Obtaining Services and Repositories in Vaadin

data_processing

One problem that you’ll face in practically any application, including a Vaadin-powered one, is getting hold of data or external services. Usually this functionality is put in some kind of service facade, or for instance a repository. Vaadin presents a problem in this regard, because it uses classes on both client (compiled to JavaScript) and server. You can’t (and don’t want to) execute service methods on the browser. Luckily, thanks to modern frameworks and good old Java, this turns out to be incredibly easy.

If you want to decouple service from client classes, there used to be a time when you would either go for some static factory pattern (please, don’t) or use some kind of JNDI lookup to get a hold of the service objects or repositories.  In modern times, you’re probably going for a dependency injection container (I like Spring, but the latest JEE6 beans have similar possibilities).

Using Spring, it’s as simple as defining a service in the Spring configuration and injecting it with the @Autowired annotation. With a little setup, this works perfectly in Vaadin.

I don’t think I’m telling anything new here, neither is the next part, but the combination makes for very non-intrusive, clean code.

If you start adding @Autowired annotations everywhere, you’ll soon end up with errors: Vaadin requires that any Java class is serializable. This is necessary to transmit information between the JavaScript web browser client application and the Java server code. Serialized object are sent between the two, to keep the internal states in sync.

However, many service classes won’t be serializable. A typical JPA repository will depend on an entity manager, which is not serializable.

The solution, is to mark those fields as “transient“, an often forgotten Java keyword that excludes fields from being serialized (among other things). The great thing about the @Autowired annotation is that it will inject dependencies every time a Java object is constructed. Also when it is de-serialized.

So each time the client sends an object, when it is constructed on the server, it will get autowired with your services.

It’s just that easy:

  1. Mark your dependencies toward services with @Autowired.
  2. Make them transient so that they don’t get serialized.

(image credit)

If you liked this, why not share it with your friends?
    This entry was posted in Java and JavaScript. Bookmark the permalink. Both comments and trackbacks are currently closed.

    2 Comments

    1. Marc
      Posted March 19, 2010 at 12:16 pm | Permalink

      Actually, there is a rather big misunderstanding here: Vaadin does not require things to be serializable, and does not use serialization to keep the client ans the server in sync. Vaadin is serializable mainly so that it can be run on App Engine (of course there are other scenarios when it's handy too). The communication between the client and the server is handled via JSON, and classes are not shared between the two – all the classes used on the client reside in the .gwt.client package. The result is basically that you code Vaadin _exactly_ as if it was a server-side-only framework, until you need some custom component that can not be made using composition.

    2. Posted March 22, 2010 at 9:27 pm | Permalink

      Aha, thanks Marc for the explanation! I'll update the post to reflect this newfound knowledge.
      I haven't gotten into custom components yet, so I didn't know how they are implemented. But it sounds logical that the component creator controls how and what gets send over the wire.
      Thanks again for sharing your knowledge.

    2 Trackbacks

    1. [...] It’s fairly easy to do the authentication by yourself. I created a nice Vaadin form for username and password input and used this post to authenticate the user. I used the Spring annotation based injection to get to my authentication provider. I’ve detailed this method in a previous post. [...]

    2. By Google AppEngine for Java Loading Request Analysis on September 7, 2010 at 10:03 am

      [...] A similar application, but now the bean is injected via annotations and there is no direct access to the Spring application context in the Vaadin application. I explained this technique for obtaining Spring beans in a non-Spring-managed object earlier. [...]

    • Feedback or questions? Contact me right away.

      Comments have been disabled on my posts. Not because I don't want to hear from you, but because they were adding very little to the conversation (most of them were spam anyway). I do listen to you and try to keep as much posts as possible up-to-date and error free. So if you have a question, if something isn't working the way you hoped or you have general feedback, please use the contact form below. I guarantee an answer to every honest question or remark.
    • Get in touch
      1. (required)
      2. (valid email required)
       

      cforms contact form by delicious:days