I've been working on an update to this site that adds blogging & commenting features. It's a Spring + JPA site, so I created a Post object and a PostDAO and built all the new features using those classes. Everything worked perfectly until I implemented the delete controller. When trying to delete a Post, I was getting the following exception:
org.springframework.dao.InvalidDataAccessApiUsageException: Removing a detached instance com.musicstore.model.Post
I debugged the exception, searched all over the place and couldn't figure what was causing the exception, which was occurring within a getJpaTemplate().remove(post) call. After an hour or two of fruitless googling, I decided to read up on JpaSupport (which the PostDAO extends) and look more closely at my code. I finally realized what the problem was when I noticed that JpaSupport provides callbacks when you need to access an EntityManager directly – but I wasn't using them...
The problem originated in a find method that was happening before the delete. In this method I need to specify how many results to return, and so JpaSupport's find wrapper methods weren't sufficient – I need to access the EntityManager directly. So I was getting an EntityManager like this:
public ListfindSetOfPosts(Integer firstResult, Integer maxResults) { EntityManager em = getJpaTemplate().getEntityManagerFactory().createEntityManager(); // do stuff with the EntityManager... }
This created an EntityManager, and the find query did work. However, when I called getJpaTemplate().remove(post), the post I had found was now detached. The solution was to get the EntityManager with a JpaCallback so that JpaSupport can manage the EntityManager correctly, like so:
public ListfindSetOfPosts(final Integer firstResult, final Integer maxResults) { return (List ) getJpaTemplate().execute(new JpaCallback() { @Override public Object doInJpa(EntityManager em) throws PersistenceException { // do stuff with the EntityManager... } } }
After I switched to this method of obtaining an EntityManager, everything worked perfectly.