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.

Dynamically create Spring beans from groovy scripts at runtime

February 24th, 2009 by Marius Hanganu in Java, General


In the current project – a java based CMS – we were faced with an interesting problem: how can we dynamically create renderers to power our blocks in the html page (currently all renderers are Java classes and Spring beans also described in the application context files).

Imagine the power of this approach. Especially when Java deployments can be quite a hassle in a multi server environment (deploying sources on the linux machines, wait for a good moment for starting/stopping the servers – which may or may not perform a sensitive operation at that time, synchronize the restart of the web servers, check log files for any errors, etc).

What could be better than having your Spring beans dinamically created from the administration panel? No server restarts, no deployments. Just keep your Groovy scripts in the database and make any modification realtime.

Achieving the programatic creation of Spring beans from groovy scripts can be done in four steps:

1. load the groovy script and parse it into a java Class
2. create a bean definition using the previously loaded class
3. inject any other beans into your bean definition
4. register the bean definition and get a handle on the bean created

Of course, you cannot declare variables as instances of the Java class defined in the groovy script. Or you may do it programatically through reflection. But it is much simpler (if the project suits these needs) to have a base interface for all your dynamic beans and after those 4 steps, simply cast the bean created to the Java interface. So you might add two more steps to the previous four:

0. declare a base interface for your all your classes declared in groovy scripts
5. cast the created bean to the base interface so that you can use it in your code

The code is actually pretty simple. But you can hardly find any article/post on the subject. Most of them discuss an older version of Spring (1.x), while my code had to work with Spring 2.0.x – which is completely different in terms of the API calls needed to create a bean.

public class GroovyTemplateEngineImpl extends DefaultListableBeanFactory implements ApplicationContextAware {
    public BaseInterface createOrUpdateBean(String rendererName, String code) throws Exception, ClassNotFoundException {
        // 1. load the groovy script and parse it into a class
        GroovyClassLoader gcl = new GroovyClassLoader(getClassLoader());
        Class clazz = gcl.parseClass(groovyScriptAsAString);
        // 2. create the bean definition
        AbstractBeanDefinition beanDef = BeanDefinitionReaderUtils.createBeanDefinition( "parentBean", packageName + "." + className, gcl);
        // 3. inject here any attributes that would normally be passed using spring XML configuration files
        beanDef.setAttribute("attr1", bean1);
        DefaultListableBeanFactory factory = (DefaultListableBeanFactory) appCtx.getAutowireCapableBeanFactory();
        // 4. Create the bean - I'm using the class name as the bean name
        factory.registerBeanDefinition(className, beanDef);
        Object bean = factory.createBean(clazz, AUTOWIRE_BY_NAME, false);
        // 5. further on you can cast it to any interface
        return (BaseInterface) bean;

You will also need to add to the previous class a setter for application context to be injected (the class needs to implement ApplicationContextAware).

Please note that this code only works from spring version 2.0.3 and up. If you’re using a lower version, you’ll likely encounter this exception:

Caused by: org.aspectj.weaver.reflect.ReflectionWorld$ReflectionWorldException: 
warning can't determine implemented interfaces of missing type .... 

Good luck groovying!