title: spring jpa setup cannot update database
body: <p>I'm a long time reader, first time poster.</p>
  
  <p>Essentially I'm writing a web app based on the <a href="http://blog.springsource.com/2010/07/22/spring-mvc-3-showcase/" rel="nofollow">spring 3 showcase</a>.</p>
  
  <p>Subsequently I plugged in the ability to write to a database based on <a href="http://paulszulc.wordpress.com/2010/01/09/jpa-2-0-and-spring-3-0-with-maven/" rel="nofollow">this tutorial</a>.</p>
  
  <p>My integration tests that test all the ORM stuff appear happy however when I deploy my project to tomcat and attempt to do a db update via the website the database does not update!</p>
  
  <p>Configuration:</p>
  
  <p>appContext.xml</p>
  
  <pre><code>&lt;!-- holding properties for database connectivity / --&gt;
  &lt;context:property-placeholder location="classpath:jdbc.properties" /&gt;
  &lt;!-- enabling annotation driven configuration / --&gt;
  &lt;context:annotation-config /&gt;
  &lt;context:component-scan base-package="wcpackage" /&gt;
  &lt;tx:annotation-driven transaction-manager="transactionManager" /&gt;
  
  &lt;bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" /&gt;
  
  &lt;bean id="dataSource"
      class="org.springframework.jdbc.datasource.DriverManagerDataSource"
      p:driverClassName="${jdbc.driverClassName}" p:url="${jdbc.url}" /&gt;
  
  &lt;bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"
      p:entityManagerFactory-ref="entityManagerFactory" /&gt;
  
  &lt;bean id="entityManagerFactory"
      class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
      p:dataSource-ref="dataSource" p:jpaVendorAdapter-ref="jpaAdapter"&gt;
      &lt;property name="loadTimeWeaver"&gt;
          &lt;bean
              class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver" /&gt;
      &lt;/property&gt;
      &lt;property name="persistenceUnitName" value="wctemplatePU"&gt;&lt;/property&gt;
  &lt;/bean&gt;
  
  &lt;bean id="jpaAdapter"
      class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"
      p:showSql="${jpa.showSql}" /&gt;
  </code></pre>
  
  <p>jdbc.properties</p>
  
  <pre><code>jpa.database=gm
  jpa.showSql=true
  jdbc.driverClassName=com.mysql.jdbc.Driver
  jdbc.url=jdbc:mysql://localhost:3306/gm?user=gmuser&amp;password=gmuser
  </code></pre>
  
  <p>persistence.xml</p>
  
  <pre><code>&lt;persistence xmlns="http://java.sun.com/xml/ns/persistence"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://java.sun.com/xml/ns/persistence"&gt;
  
  &lt;persistence-unit name="wctemplatePU" transaction-type="RESOURCE_LOCAL"&gt;
      &lt;properties&gt;
          &lt;property name="hibernate.hbm2ddl.auto" value="validate" /&gt;
      &lt;/properties&gt;
  &lt;/persistence-unit&gt;
  </code></pre>
  
  <p></p>
  
  <p>Code that should commit to the db</p>
  
  <pre><code>    @Transactional(propagation=Propagation.REQUIRED, rollbackFor=Exception.class)
  protected Sequence persistGame(PGNGame game) {
      Sequence seq = new Sequence();
      seq.setType(SequenceType.GAME);
      seq.setEvent(game.getTag("Event"));
      seq.setSite(game.getTag("Site"));
  
              ...
  
      sequenceDao.persist(seq);
  
      return seq;
  }
  </code></pre>
  
  <p>SequenceDao is essentially</p>
  
  <pre><code>public abstract class JpaDao&lt;K, E&gt; implements Dao&lt;K, E&gt; {
  protected Class&lt;E&gt; entityClass;
  
  @PersistenceContext
  protected EntityManager entityManager;
  
  public JpaDao() {
      ParameterizedType genericSuperclass = (ParameterizedType) getClass().getGenericSuperclass();
      this.entityClass = (Class&lt;E&gt;) genericSuperclass.getActualTypeArguments()[1];
  }
  
  public void persist(E entity) { entityManager.persist(entity); }
  
  public void remove(E entity) { entityManager.remove(entity); }
  
  public E findById(K id) { return entityManager.find(entityClass, id); }
  }
  </code></pre>
  
  <p>I get no errors of any sort I can see in the console/logs.  What am I doing wrong?</p>
  
  <p>One thing I notice when I crank up the hibernate logging to DEBUG</p>
  
  <pre><code>DEBUG:org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler - Creating new EntityManager for shared EntityManager invocation
      DEBUG: org.hibernate.impl.SessionImpl - opened session at timestamp: 12975078282
      DEBUG: org.hibernate.event.def.AbstractSaveEventListener - delaying identity-insert due to no transaction in progress
      DEBUG: org.hibernate.event.def.AbstractSaveEventListener - delaying identity-insert due to no transaction in progress
      DEBUG: org.springframework.orm.jpa.EntityManagerFactoryUtils - Closing JPA EntityManager
  </code></pre>
  
  <p>TRACE log is</p>
  
  <pre><code>DEBUG:org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler - Creating new EntityManager for shared EntityManager invocation
  DEBUG: org.hibernate.impl.SessionImpl - opened session at timestamp: 12975085724
  TRACE: org.hibernate.engine.IdentifierValue - id unsaved-value: 0
  TRACE: org.hibernate.event.def.AbstractSaveEventListener - transient instance of: net.samuelbergin.gm.model.Player
  TRACE: org.hibernate.event.def.DefaultPersistEventListener - saving transient instance
  TRACE: org.hibernate.event.def.AbstractSaveEventListener - saving [net.samuelbergin.gm.model.Player#&lt;null&gt;]
  TRACE: org.hibernate.engine.Cascade - processing cascade ACTION_PERSIST_SKIPLAZY for: net.samuelbergin.gm.model.Player
  TRACE: org.hibernate.engine.Cascade - done processing cascade ACTION_PERSIST_SKIPLAZY for: net.samuelbergin.gm.model.Player
  TRACE: org.hibernate.event.def.WrapVisitor - Wrapped collection in role: net.samuelbergin.gm.model.Player.sequenceList
  DEBUG: org.hibernate.event.def.AbstractSaveEventListener - delaying identity-insert due to no transaction in progress
  TRACE: org.hibernate.engine.Cascade - processing cascade ACTION_PERSIST_SKIPLAZY for: net.samuelbergin.gm.model.Player
  TRACE: org.hibernate.engine.Cascade - cascade ACTION_PERSIST_SKIPLAZY for collection: net.samuelbergin.gm.model.Player.sequenceList
  TRACE: org.hibernate.engine.CascadingAction - cascading to persist: net.samuelbergin.gm.model.Sequence
  TRACE: org.hibernate.engine.IdentifierValue - id unsaved-value: 0
  TRACE: org.hibernate.event.def.AbstractSaveEventListener - transient instance of: net.samuelbergin.gm.model.Sequence
  TRACE: org.hibernate.event.def.DefaultPersistEventListener - saving transient instance
  TRACE: org.hibernate.event.def.AbstractSaveEventListener - saving [net.samuelbergin.gm.model.Sequence#&lt;null&gt;]
  TRACE: org.hibernate.engine.Cascade - processing cascade ACTION_PERSIST_SKIPLAZY for: net.samuelbergin.gm.model.Sequence
  TRACE: org.hibernate.engine.Cascade - done processing cascade ACTION_PERSIST_SKIPLAZY for: net.samuelbergin.gm.model.Sequence
  TRACE: org.hibernate.event.def.WrapVisitor - Wrapped collection in role: net.samuelbergin.gm.model.Sequence.commentList
  TRACE: org.hibernate.engine.IdentifierValue - id unsaved-value: 0
  DEBUG: org.hibernate.event.def.AbstractSaveEventListener - delaying identity-insert due to no transaction in progress
  TRACE: org.hibernate.engine.Cascade - processing cascade ACTION_PERSIST_SKIPLAZY for: net.samuelbergin.gm.model.Sequence
  TRACE: org.hibernate.engine.Cascade - cascade ACTION_PERSIST_SKIPLAZY for collection: net.samuelbergin.gm.model.Sequence.commentList
  TRACE: org.hibernate.engine.Cascade - done cascade ACTION_PERSIST_SKIPLAZY for collection: net.samuelbergin.gm.model.Sequence.commentList
  TRACE: org.hibernate.engine.Cascade - done processing cascade ACTION_PERSIST_SKIPLAZY for: net.samuelbergin.gm.model.Sequence
  TRACE: org.hibernate.engine.Cascade - done cascade ACTION_PERSIST_SKIPLAZY for collection: net.samuelbergin.gm.model.Player.sequenceList
  TRACE: org.hibernate.engine.Cascade - done processing cascade ACTION_PERSIST_SKIPLAZY for: net.samuelbergin.gm.model.Player
  DEBUG: org.springframework.orm.jpa.EntityManagerFactoryUtils - Closing JPA EntityManager
  TRACE: org.hibernate.impl.SessionImpl - closing session
  </code></pre>
  
  <p>Entity definition</p>
  
  <pre><code>@Entity
  @Table(name="sequences")
  public class Sequence {
      @Id
      @GeneratedValue
      private int id;
      @Enumerated(EnumType.STRING)
      private SequenceType type;
      private String event;
      private String site;
      @Temporal(TemporalType.DATE)
      private Date date;
      private int round;
      private String result;
      private String eco;
      private String description;
      private String moves;
      @ManyToOne
      private Player whitePlayer;
      @ManyToOne
      private Player blackPlayer;
      @OneToMany(cascade={CascadeType.ALL})
      @JoinTable(name="sequenceComments",
              joinColumns={@JoinColumn(name="sequence_fk")},
              inverseJoinColumns={@JoinColumn(name="comment_fk")})
      private List&lt;Comment&gt; commentList = new ArrayList&lt;Comment&gt;();
          ...
  </code></pre>
  
  <p>Controller</p>
  
  <pre><code>@Controller
  @RequestMapping("/fileupload")
  public class FileUploadController {
  
      private static Logger logger = LoggerFactory.getLogger(FileUploadController.class);
  
      @Autowired private SequenceService sequenceService;
  
      @RequestMapping(method=RequestMethod.POST)
      public void processUpload(@RequestParam MultipartFile file, HttpServletRequest request, Model model) throws IOException {
          //TODO: parse pgn
          List&lt;PGNGame&gt; pgnGameList;
          String filename = file.getOriginalFilename();
          try {
              pgnGameList = PGNProcessor.parse(file.getInputStream());
  
              sequenceService.createSequences(pgnGameList);
  
              String message = "File '" + filename + "' uploaded successfully";
              model.addAttribute("message", new Message(MessageType.success, message));
  
          } catch (PGNProcessorException ppe) {
              logger.error("Failed to process "+filename, ppe);
              model.addAttribute("message", new Message(MessageType.error, "Failed to process "+filename+".  Reason: "+ppe.getMessage()));
          }
          // else whole html pg is rendered instead of just a div to update
          model.addAttribute("ajaxRequest", AjaxUtils.isAjaxUploadRequest(request));  
      }
  }
  </code></pre>
  
  <p>Service</p>
  
  <pre><code>public class JpaSequenceService implements SequenceService {
  
      ...
  
  public List&lt;Sequence&gt; createSequences(List&lt;PGNGame&gt; gameList) {
      List&lt;Sequence&gt; seqList = new ArrayList&lt;Sequence&gt;();
      for (PGNGame game : gameList) {
          Sequence seq = persistGame(game);
          seqList.add(seq);
      }
      return seqList;
  }
  
  @Transactional(propagation=Propagation.REQUIRED, rollbackFor=Exception.class)
  protected Sequence persistGame(PGNGame game) {
          /*...as above...*/
  }
  </code></pre>