Spring+JPA with MySQL/Oracle configurations

September 6th, 2010 by Ioan Cocan in Java, General, Spring Framework

Spring Framework

During development for a solution based on Spring+JPA+MySQL/Oracle we came across two settings to watch for.

1. Database isolation level

The default isolation level in MySQL is REPEATABLE READ, different from the default in Oracle (READ_COMMITTED). It seems this is kept for historical reasons related to the replication. Still, the effect is that for example a database query will return the same result, no matter if some other transaction has meanwhile changed the database.

For checking the current MySQL isolation level: SELECT @@GLOBAL.tx_isolation, @@tx_isolation;

For changing the isolation level add: “transaction-isolation = REPEATABLE-READ” to you MySQL configuration.

2. JPA transaction configuration

For those accustomed to Hibernate default configuration, the default JpaTransactionManager comes with a different default for behavior related to transaction configuration. The “globalRollbackOnParticipationFailure” is set to true, that means a failed transaction will trigger a global rollback. If you want to change that and be the decision maker if the global transaction should be rolled back or not, set globalRollbackOnParticipationFailure to false.


Springy: org aspectj weaver reflect ReflectionWorld ReflectionWorldException: warning can’t determine implemented interfaces of missing type

March 30th, 2009 by Marius Hanganu in Java, General, Spring Framework

Here’s a quick one: if you’ve encountered the following error

org.springframework.beans.factory.BeanCreationException: Error creating bean with name '...': Initialization of bean failed; nested exception is org.aspectj.weaver.reflect.ReflectionWorld$ReflectionWorldException: warning can't determine implemented interfaces of missing type ...
 [Xlint:cantFindType]
Caused by: org.aspectj.weaver.reflect.ReflectionWorld$ReflectionWorldException: warning can't determine implemented interfaces of missing type ro.tremend.bigg.web.tile.currencyCustomTileRenderer2
 [Xlint:cantFindType]
	at org.aspectj.weaver.reflect.ReflectionWorld$ExceptionBasedMessageHandler.handleMessage(ReflectionWorld.java:163)

And didn’t figure out yet what was the problem, you may want to check your spring version. This error happens in 2.0.2  but it seems it was fixed since 2.0.5.

More here


Avoid Spring circular references and over eager type matching using lazy initialization

April 5th, 2007 by Marius Hanganu in Java, General, Spring Framework

Circular dependencies between beans managed by Spring is usually caused by a logic error, but it may be sometimes exactly what developers intend to obtain.

We recently ran into this problem: Spring seems to “over-eagerly” initialize the beans, resulting in an circular dependency error.

2007-04-05 13:24:41,310 ERROR [main] context.ContextLoader (ContextLoader.java:205) – Context initialization failed
org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name ‘articleManager’: Bean with name ‘*********’ has been injected into other beans [******, **********, **********, **********] in its raw version as part of a circular reference,
but has eventually been wrapped (for example as part of auto-proxy creation). This means that said other beans do not use the final version of the bean. This is often the result of over-eager type matching – consider using ‘getBeanNamesOfType’ with the ‘allowEagerInit’ flag turned off, for example.

We managed to overcome the problem by using the “lazy-init” attribute for our Spring beans. Other techniques for avoiding/fixing the problems are described by Costin Leau and Andreas Senft on the spring framework’s forums here and here.


Chaining multiple view resolvers in Spring – using two InternalResourceViewResolver

March 1st, 2007 by Marius Hanganu in Java, General, Spring Framework

Spring allows chaining of multiple view resolvers . However, there are some view resolvers like the ones extending UrlBasedViewResolver which must be the last in the chain, hence the limitation of having only one such view resolver in your chain.
Javadoc for UrlBasedViewResolver mentions: “Note: When chaining ViewResolvers, a UrlBasedViewResolver always needs to be last, as it will attempt to resolve any view name, no matter whether the underlying resource actually exists.”

There are however situations in which one needs chaining multiple view resolvers such as InternalResourceViewResolver or UrlBasedViewResolver. For example, you need to support views returned both as JSP pages and Tiles layouts.

Chaining two InternalResourceViewResolver won’t do the job, since the first one will always try to resolve your view, and it will fail either on the JSP page or Tiles layout.

In order to support this feature you have to write your own view resolver extending UrlBasedViewResolver. Here’s an idea on how you can chain these resolvers: your custom view resolver can analyze the view returned by your Spring MVC controller and check its name. If it’s name contains the suffix “.layout”, your ViewResolver will pass control to the other view resolvers in the chain. Here’s a sample code:

/**
* Custom view resolver – checks if view name contains string layout, in which case lets the request
* reach the other view resolvers in the chain
*
* @author Marius Hanganu
*/
public class MyViewResolver extends UrlBasedViewResolver implements Ordered {
    /**
    * Overrides loadView in UrlBasedViewResolver to be able to make a     difference when letting the other views
    * in the chaing take control of the request
    *
    * @see org.springframework.web.servlet.view.UrlBasedViewResolver#loadView(String,java.util.Locale)
    */
    protected View loadView(String viewName, Locale locale) throws Exception {
    AbstractUrlBasedView view = buildView(viewName);
    View viewObj = (View)     getApplicationContext().getAutowireCapableBeanFactory().initializeBean(view, viewName);
        if (viewObj instanceof JstlView) {
            JstlView jv = (JstlView) viewObj;
            if (jv.getBeanName().indexOf(“layout”) != -1) {
                return null;
            }
        }

        return viewObj;
    }
}

The only other thing one needs to do is to declare the view resolvers.

<bean id=”viewResolver” class=”ro.tremend.bigg.web.spring.BiggViewResolver”>
    <property name=”order” value=”1″/>
    <property name=”viewClass” value=”org.springframework.web.servlet.view.JstlView”/>
    <property name=”prefix” value=”/WEB-INF/jsp/”/>
    <property name=”suffix” value=”.jsp”/>
</bean>

<bean id=”tilesViewResolver” class=”org.springframework.web.servlet.view.InternalResourceViewResolver”>
    <property name=”order” value=”2″/>
    <property name=”requestContextAttribute” value=”requestContext”/>
    <property name=”viewClass” value=”org.springframework.web.servlet.view.tiles.TilesJstlView”/>
</bean>


My experience with web services with Spring, Axis, XFire

January 22nd, 2007 by spostelnicu in Java, General, Spring Framework

First thing to note is that, this being my first contact with web services (SOAP and WSDL), it took me quite a lot of time (almost five working days) to learn about the technologies involved and try to implement and publish a web service in my application.

Of these four and a half working days (36 hours), about 14 cumulated hours were spent stepping through the library code, trying to determine the causes for various errors (especially for XFire, which returned all sorts of cryptic and unhelping error messages).

1) First try: Apache Axis

The first day was dedicated to learning about Axis and trying what it can do.

The second day was dedicated to writing and testing the necessary configurations to publish my specific service, which contained many service methods and serializable classes.

My opinion after this short experience is this: the setting up of the service with Axis seems to be too complicated for my simple needs.

After writing the service interface, you have to run two tools: Java2WSDL and WSDL2Java. The first one will generate the WSDL for the web service. The second one will generate auxilliary classes: remote interface, client stub, service locator helper – all of them hard-coded for my service.

Of course, to integrate them into a build process you have to learn to use the ant tasks for Java2WSDL and WSDL2Java, and after the code generation, compile the generated files.

And then you have to take care of the deployment of the service by using the generated deployment.xml, and I didn’t quite understand how to automate the deployment (the documentation was not very clear about this).

All I needed was some kind of generic Java class to expose web services by proxying SOAP calls to a Spring managed bean that implemented my interface. Something like: WebServiceFactory.create(MyServiceInterface.class).

I didn’t want no WSDL or XMLSchema or namespaces or some other messy XML stuff.

And for the client part, something like this was desirable: WebServiceProxyFactory.create(MyServiceInterface.class)

Which, fortunately, I actually found the next day in the form of XFire.

2) Second try: XFire

The third day I decided to switch to XFire, because of its simpler usage (no more WSDL, no more deployment.xml, no more two-steps build with Java2WSDL and WSDL2Java…)

So I tried to learn about services.xml and xfire-servlet.xml and stuff.

The first thing that sticks out is the “not-so-complete” documentation and with the way that XFire just doesn’t like to show useful error messages. Most of the errors are either silently ignored, or replaced by some generic message like “Invalid SOAP request”.

One big problem that I had was that at first I tried to access the XFire service with the Axis client that I already have. Big mistake! After half a day of stepping through the XFire code, I discovered that the problem was that my client was sending a request as RPC/encoded, which XFire does not support. And instead of telling me that, XFire was simply returning a fault with the internal exception message, which was: “ Index: 1, Size: 1 “.

Imagine my frustration! I didn’t have any clue as to what this can mean. Could it have something to do with the SOAP elements? Could it be some internal tables used? Could it mean the index of the method parameters? And, most annoying: is this an ERROR MESSAGE? What is the error? “Index: 1, Size: 1” – I don’t see any error in here!

Of course searching the web didn’t help me in this case, so I started debugging the XFire service handlers, and learning the XFire insides along the way.

After about an hour I discovered that this was no more than an IndexArrayOutOfBoundsException! It seems I haven’t met one very often in my days, otherwise I could have been able to recognise the error message. But XFire didn’t return in the fault message the name of the exception, it returned just the error message. And no error logging. And of course, do not even dare to ask a stacktrace.

Anyway, eventually I discovered that the exception was caused because the handler wasn’t able to recognise the format of the SOAP request, which contained multiref elements. After googling some more and not finding any reference to multiref and XFire, I eventually found that the multirefs were there because of the RPC/encoded format – which, no need to mention, I had very little knowledge about. Remember, this was my first contact with SOAP, and I wasn’t in the mood to learn all the “subtleties” of the protocol. I just wanted to expose my service with the least effort.

The fourth day I learned how to expose services with XFire by using JSR 181 Annotations. Because of the incomplete documentation and examples, this caused a problem that took me 3 hours to debug and still couldn’t solve until next day: the service class wasn’t accesible through XFire, which just kept returning empty pages (another annoying behaviour: no error message, no 404, no service fault, no “Invalid SOAP request”, no nothing. Just a blank page with the footer “Generated by XFire”)

I couldn’t tell if it was a problem with SimpleUrlMapper, or with Jsr181HandlerMapping, or if I should use DispatcherServlet instead of XFireSpringServlet…

The documentation contained very confusing examples, in which a SimpleUrlMapper had a mapping from “/” to handlerMapping, and handlerMapping was a Jsr181HandlerMapping. My confusion was: what does Jsr181HandlerMapping do? It’s another URL mapper? And if it is, when are the Spring beans initialized?

The next morning I finally discovered the cause for the last problem encountered.

After yet another session of analysing the XFire source code, it was clear for me that Jsr181HandlerMapping was not an URL mapper. Actually, all it did was to call XFire to register my classes that had @WebService annotations. But then again, why didn’t it work?

To configure this part, I followed an example that I found on some blog, because the XFire documentation lacked this part. I actually followed exact steps showed in the example, along with the example classes and settings. And what frustrated me more was that his conclusion was “So we see that setting up web services by using XFire and JSR 181 annotations is a no brainer.” If it is a no brainer, why it doesn’t work ?! :p

But apparently the author of the example forgot to mention that in order for this to work, you have one more thing to configure: to add your bean in applicationContext.xml

In his example this step was missing, so of course the service was not registered, because (as I found out after analysing the XFire source code) Jsr181HandlerMapping checked all the already configured beans to see if they had @WebService annotation.

So in conclusion:

  • XFire is indeed very easy to configure (if you follow a complete example, like this one that I found later), but lacks many “advanced” SOAP features.
  • Axis is more advanced, more configurable and with more advanced SOAP and WSDL features, but a “little” bit more difficult to configure.

technorati tags:, , , , ,


Spring and Tiles – presentation tier in http://www.123urban.ro

November 1st, 2006 by Marius Hanganu in Java, General, Spring Framework

Presentation tier in 123urban – Spring comes to the rescue as usual with its embedded support for Tiles. Basically, the only setting is to change your viewResolver in your -servlet.xml from JstlView to TilesView.

   <bean id=”viewResolver” class=”org.springframework.web.servlet.view.InternalResourceViewResolver”>        
<property name=”requestContextAttribute” value=”requestContext”/>
<property name=”viewClass” value=”org.springframework.web.servlet.view.tiles.TilesJstlView”/>
</bean>

Notice the use of TilesJstlView a specialization of TilesView which offers support for JSTL pages.

From here on is just as easy as a walk in the park – classic Tiles -> tiles.xml stays in WEB-INF and works like a charm. You should be aware that from now on all your responses will go through Tiles which means all your Spring MVC controllers will have to define their views as being Tiles layouts.


End to end UTF-8 encoding usage with MySql and Spring

August 25th, 2006 by Ioan Cocan in Java, General, Spring Framework
Setting up a solution to store, manage and display UTF-8 data using MySql was quite a challenge.There are some a few steps that you have to get right, otherwise garbage data will come out at various stages in your application.

Inserting the data

First, make sure your data is UTF-8. You can easily check this with a text editor or maybe your favourite IDE. Next, create the database and tables specifying the character encoding as UTF-8. Here is a sample.

CREATE TABLE `word` ( `Id` int(11) NOT NULL auto_increment, `Name` varchar(30) NOT NULL default ”, `Dname` varchar(40) NOT NULL default ”, UNIQUE KEY `counter` (`Id`), KEY `alfabetic` (`Name`), KEY `dname` (`Dname`), ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Unfortunately, I have not found a Mysql tool to handle UTF-8 files properly. Opening such file would just result in unreadable characters in tool display and also in database. Still, using command line console would result in the same unreadable charaters. The solution: make sure you are setting the character set of the imported data. You can to that using:

SET NAMES UTF-8;

Selecting inserted data

The Mysql JDBC driver allows setting several parameters as connection string parameter. The connection URL would look like:

connection.url=jdbc:mysql://localhost/t1?useUnicode=true&characterEncoding=UTF-8

Still, setting up Spring using default BasicDataSource would do affect character encoding settings.

<bean id="dataSource" class=" org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="${connection.driver_class}"/>
<property name="url" value="${connection.url }"/>
<property name="username" value="${connection.username}"/>
<property name="password" value="${connection.password}"/>
</bean>

In order to check used parameters for a particular connection, check using a statement like: "SHOW VARIABLES LIKE ‘char%’" Most variables should be UTF-8, at least the client connection property must be UTF-8. In order to have it working, I’ve added a custom data source that would directly add parameters to the driver when creating the connection:

public class CustomDataSource extends BasicDataSource {
public void init() {
addConnectionProperty("useUnicode", "true");
addConnectionProperty("characterEncoding", "UTF-8");
}
}

That can be easily wired in Spring same as the data source above, only with a "init-method" definition that would add the desired connection properties. The really hard part, that took me a while to figure out, was selecting data using a UTF-8 string in the WHERE clause. It all comes down to the collation Mysql is using in comparing the data. Without any collation specified, searching a UTF-8 string would result in ignoring the accents or special characters and match more results.

The solution, specify the collation when you are doing the query: select Id, Name, Dname from word where w.Dname=#param# COLLATE utf8_bin;

Display data in a web page

Spring MVC proves a simple solution for implementing the web layer. There are several things to be done: – set proper encodings in JSP pages. This can be easily done with a filter or including the following in all your pages. <%@ page language="java" pageEncoding="UTF-8" contentType="text/html;charset=utf-8" isELIgnored="false"%>

– set meta information in the "head" section of the JSP file <META http-equiv="Content-Type" content="text/html; Submit and handle data from a web page

UTF-8 characters have to be URL encoded before submission, this is easily done in three steps.

First, set the URIEncoding property in the Connector definition:

<Connector port="8080" URIEncoding="UTF-8" useBodyEncodingForURI="true" maxThreads="150" minSpareThreads="25" maxSpareThreads="75" enableLookups="false" redirectPort="8443" acceptCount="100" debug="0" connectionTimeout="20000" disableUploadTimeout="true" />

That allows the conversion of URLs to UTF-8 and correct submission of parameters using GET method. Second, use encodeURIComponent() in your JavaScript code to encode all submitted data. Without this, even if your page is UTF-8, your parameters will not be handled properly (at least not by IE, Firefox seems to have no problem with this). Third, do not read any parameters in your Controller classes unless you’ve set the right encoding for your request. This can be done using a filter or simply by setting:

request.setCharacterEncoding("UTF-8");

Versions: Mysql 5.0.19/ Mysql Connector 3.1.13/ Spring 1.2.7