No inserts using Hibernate and Spring

I was setting up a simple side-project with Spring, Spring Data and Hibernate. My repositories are generated using Spring Data’s jpa:repositories to save on development time and the database schema is generated using Hibernate, based on my JPA and JSR-303 annotated entities.

However, one of the issues I encountered was that my repositories did not insert anything in the database. After searching the web I followed a suggestion on Stackoverflow to add an entityManager.flush() to the repository to see if a transaction was running or not. There was indeed no transaction running but I had yet to find out why.

Exception in thread "main" javax.persistence.TransactionRequiredException: no transaction is in progress
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.checkTransactionNeeded(AbstractEntityManagerImpl.java:1136)
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.flush(AbstractEntityManagerImpl.java:1297)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.invoke(ExtendedEntityManagerCreator.java:344)
at com.sun.proxy.$Proxy31.flush(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:293)
at com.sun.proxy.$Proxy31.flush(Unknown Source)
at be.pw999.photocol.service.PhotoColServiceImpl.makeImage(PhotoColServiceImpl.java:45)
...

At that point my code looked like this:

@Service
public class PhotoColServiceImpl implements PhotoColService {

// My Injected beans

@Autowired
private EntityManager em;

@Transactional(readOnly = false)
@Override
public MakeImageResponse makeImage(MakeImageRequest request) {
em.flush();
}
}

 

 

public class Backend {

 public static void main(String[] args) {
  ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("classpath:/META-INF/webapp/WEB-INF/application-context.xml");
  
  PhotoColService service = ac.getBean(PhotoColService.class);
  
  MakeImageRequest r = new MakeImageRequest("DSC0012.JPG", "/home/phillip/Pictures", "12345678901234567890123456789012");
  MakeImageResponse resp = service.makeImage(r);
  
  ac.close();
 }
}

 

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd
http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.8.xsd">

 <context:component-scan base-package="be.pw999.photocol.service"></context:component-scan>
 <!-- Define your application beans here. They will be available to the
beans defined in your web-context because it is a sub-context. Beans defined
in the web-context will not be available in the application context. -->
 <context:property-placeholder location="classpath:persistence-h2.properties" />

 <bean id="sessionFactory"
class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
  <property name="dataSource" ref="dataSource" />
  <property name="packagesToScan" value="be.pw999.photocol.model" />
  <property name="hibernateProperties">
   <props>
    <prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop>
    <prop key="hibernate.dialect">${hibernate.dialect}</prop>
   </props>
  </property>
 </bean>

 <bean id="dataSource" class="org.apache.tomcat.dbcp.dbcp.BasicDataSource">
  <property name="driverClassName" value="${jdbc.driverClassName}" />
  <property name="url" value="${jdbc.url}" />
  <property name="username" value="${jdbc.user}" />
  <property name="password" value="${jdbc.pass}" />
 </bean>

 <bean id="transactionManager"
class="org.springframework.orm.hibernate5.HibernateTransactionManager">
  <property name="sessionFactory" ref="sessionFactory" />
 </bean>

 <bean id="persistenceExceptionTranslationPostProcessor"
class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />

 <bean id="jpaVendorAdapter"
class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
  <property name="showSql" value="true" />
  <property name="generateDdl" value="true" />
  <property name="database" value="H2" />
 </bean>

 <bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
  <property name="dataSource" ref="dataSource" />
  <property name="jpaVendorAdapter" ref="jpaVendorAdapter" />
  <!-- spring based scanning for entity classes> -->
  <property name="packagesToScan" value="be.pw999.photocol.model" />
</bean>


 <jpa:repositories base-package="be.pw999.photocol.repository"
transaction-manager-ref="transactionManager"
entity-manager-factory-ref="entityManagerFactory"></jpa:repositories>
</beans>

There were actually a couple of issues with this configuration.

Mistake 1

Using the wrong @Transaction annotation. There are two @Transaction annotations: @javax.persistence.Transaction and @org.springframework.transaction.annotation.Transactional. Only the latter will add transaction management to your Spring services and I had used the first one (because I trust autocomplete too much).

Mistake 2

Second mistake was that I had forgotten to add <tx:annotation-driven /> to my configuration. Stupid, stupid, stupid !

Mistake 3

After solving the first two mistakes I still had no transaction and no inserts in my H2 database. I quickly realized that my transaction manager was an instance of org.springframework.orm.hibernate5.HibernateTransactionManager and even though I use Hibernate, I’m not using it directly. My repositories are generated with Spring’s jpa:repositories and they use a JPA EntityManager instead of the Hibernate SessionFactory. So even though my configuration looked great, the JPA repositories did not use the Hibernate managed transactions.

So instead of using the HibernateTransactionManager, I used the org.springframework.orm.jpa.JpaTransactionManager and this did solve the no-inserts problem.

So this is now my configuration that works:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd
http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.8.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.2.xsd">

 <context:component-scan base-package="be.pw999.photocol.service"></context:component-scan>
 <!-- Define your application beans here. They will be available to the
beans defined in your web-context because it is a sub-context. Beans defined
in the web-context will not be available in the application context. -->
 <context:property-placeholder location="classpath:persistence-h2.properties" />
 <tx:annotation-driven transaction-manager="jpaTransactionManager" />

 <bean id="sessionFactory"
class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
  <property name="dataSource" ref="dataSource" />
  <property name="packagesToScan" value="be.pw999.photocol.model" />
  <property name="hibernateProperties">
   <props>
    <prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop>
    <prop key="hibernate.dialect">${hibernate.dialect}</prop>
   </props>
  </property>
 </bean>

 <bean id="dataSource" class="org.apache.tomcat.dbcp.dbcp.BasicDataSource">
  <property name="driverClassName" value="${jdbc.driverClassName}" />
  <property name="url" value="${jdbc.url}" />
  <property name="username" value="${jdbc.user}" />
  <property name="password" value="${jdbc.pass}" />
 </bean>

 <bean id="transactionManager"
class="org.springframework.orm.hibernate5.HibernateTransactionManager">
  <property name="sessionFactory" ref="sessionFactory" />
 </bean>

 <bean id="persistenceExceptionTranslationPostProcessor"
class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />

 <bean id="jpaVendorAdapter"
class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
  <property name="showSql" value="true" />
  <property name="generateDdl" value="true" />
  <property name="database" value="H2" />
 </bean>

 <bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
  <property name="dataSource" ref="dataSource" />
  <property name="jpaVendorAdapter" ref="jpaVendorAdapter" />
  <!-- spring based scanning for entity classes> -->
  <property name="packagesToScan" value="be.pw999.photocol.model" />
 </bean>

 <bean id="jpaTransactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
  <property name="entityManagerFactory" ref="entityManagerFactory"></property>
 </bean>

 <jpa:repositories base-package="be.pw999.photocol.repository"
transaction-manager-ref="jpaTransactionManager"
entity-manager-factory-ref="entityManagerFactory"></jpa:repositories>
</beans>

Google Talk fat client refuses to start

A while ago I noticed that my Google Talk fat client didn’t want to start anymore, in fact, it did absolutely nothing. Even after reinstalling and completely removing all the caches, remaining files and registry keys, the application still wouldn’t start at all.

Google’ing for some help only resulted in more people having the same problem without a solution at all. In this post I got my first clue about the problem: FAST IO DISALLOWED.

These three words actually tell everything:
FAST IO: Google Talk is doing something special with it’s I/O’s
DISALLOWD: Windows doesn’t like Google doing this and thus refuses this action

So we have to digg a bit deeper in the (new) security features of Windows 7. As you may or may not know, Windows 7 comes with some additional security features like Address Space Layout Randomization and Structured Exception Hanlder Overwrite Protection. However, by default, these security features are not enforced to ensure a certain backwards compatibility with older applications.

Microsoft EMET

As I am and always will be a geek I have installed the Microsoft Enhanced Mitigation Experience Toolkit (EMET) which allows us to change this “opt-in behaviour” to an “opt-out behaviour”. As I’m also a bit paranoia I had configured EMET to force the “opt-out behaviour”.

Just to test it I had reverted the settings to default and after a reboot I quickly got the Google Talk window on my screen.

So, if your Google Talk fat client doesn’t start on Windows 7 then you should definately check your EMET settings.

This post was originally posted on my My.Opera blog on Thursday, February 16, 2012 6:26:15 PM. This post has been copied to my WordPress blog since the My.Opera blogging service will be discontinued.

Unable to delete executables on Windows 7

A long time ago I started to experience problems with updates from Steam. The updater deletes steam.exe before replacing it with a new version, but deleting steam.exe failed (steam.exe was deleted, but the file is still there) and the file would still be there, inaccessible to anyone and anything. The file would eventually disappear after 10 minutes, but this was kinda annoying as this also translated itself in delays when doing copy/cut-paste operations and this would also prevent me from building or re-building applications in Visual Studio.

I kinda got used to this problem and left it as it was, thinking it might be related to a driver issue or something, until last week I discoverd this was only related to executables; Windows 7 just couldn’t delete executables without a delay of 10 minutes. This bit of info was of great help because I wasn’t the only on having this problem !

The problem, unfortunately, wasn’t cause by Windows itself, but by me ! For some reason, I had disabled the “Application Experience” service. The fix is very easy (and as usual, you do everything at your own risk):
Right click Computer (on desktop or Start menu) > Manage , then under “Services and Applications”, choose “Services” . In the list you’ll find the “Application Experience” service:
Service Management

Double click on this service and change the “Startup type” from “Disabled” to “Manual”. There is no need to choose automatic, the default startup type is manual and Microsoft did choose this for a reason (I guess :P ). Just starting the service didn’t solve the problem immediately so I suggest you to restart Windows (or kill explorer.exe :mrgreen: ).
manual_startup_type

Steam updater works perfectly now and so does Visual Studio 2010 !

This post was originally posted on my My.Opera blog on Thursday, November 4, 2010 7:11:07 AM. This post has been copied to my WordPress blog since the My.Opera blogging service will be discontinued.

Fixing Windows Mobile GPS Intermediate driver

A week ago I noticed that some applications on my Windows Mobile 6.5 device stopped acquiring a GPS position where other applications did not have any problem at all. A quick test learned me that my WM managed GPS COM-port stopped sending data even tough everything was setup correctly.

After looking around a little bit on the internet I found this interesting registry key and a list of default values too:
HKEY_LOCAL_MACHINE\System\CurrentControlSet\GPS Intermediate Driver\Drivers

Using TotalCommander I started checking the values and noticed that both InputBufferSize and OutputBufferSize where set to 0. After changing these values, and those residing in the QUALGPSHarware key*, to 4096 and after rebooting my device, the GPS Intermediate Driver started working again.

*chances are that you have a different GPS(driver)

 

This post was originally posted on my My.Opera blog on Sunday, August 14, 2011 11:00:11 AM. This post has been copied to my WordPress blog since the My.Opera blogging service will be discontinued.