title: What problems can arise when mixing JPA with plain-JDBC dao implementations?
body: <p>We have two teams who want to access the same database using different technologies. One uses JPA (Hibernate, to be specific). The other uses plain JDBC.</p>
  
  <p>I've been asked to compile a list of concerns assuming that each team uses the default configuration and/or "best practices" of each technology.</p>
  
  <p>This is a new database, so imagine that the schema is being designed solely by the JPA team, or solely by the JDBC team, and then they both go about trying to access it.</p>
  
  <p>Can you please share your experiences?</p>
  
  <p><strong>UPDATE</strong>: I'm not asking for opinions here. I don't care whether JPA or JDBC is "better". I am asking for an objective list of interoperability concerns when mixing the two technologies.</p>
  
  <hr>
  
  <p>Here is an example of what I'm looking for:</p>
  
  <p>Scenario: A user reads a row, modifies it in memory, and saves it back to the database.</p>
  
  <ul>
  <li>If JPA uses optimistic locking by adding a <code>version</code> column to each table.</li>
  <li>When the transaction is committed, JPA checks if the version changed between the time that the row was read and the time it was updated. If the version changed, it throws an exception. If not, it allows the commit to continue.</li>
  <li>If the JDBC implementation uses table locks (a.k.a. pessimistic locking), they use <code>SELECT ... FOR UPDATE</code> to prevent concurrent updates.</li>
  <li><p>Imagine what happens if the JDBC implementation is not aware of the JPA convention and does not update <code>version</code> on commit:</p>
  
  <ol>
  <li>JPA reads a row using <code>SELECT</code> and sees <code>version</code> equal to 1.</li>
  <li>JDBC reads a row using <code>SELECT ... FOR UPDATE</code>.</li>
  <li>JDBC updates the row (committing its transaction) without incrementing <code>version</code>.</li>
  <li>JPA tries updating the row. The commit goes through because <code>version</code> is still equal to 1.</li>
  <li>JPA (step 4) just clobbered the update of JDBC (step 3).</li>
  </ol></li>
  </ul>
  
  <p>Lesson learned: The JDBC implementation needs to know to update the <code>version</code> column.</p>