title: JPA - Increment a numeric field through a sequence programmatically
body: <p>I have a JPA 2 web application (Struts 2, Hibernate 4 as JPA implementation only).</p>
  
  <p>The current requirement is to add a (non-id) numeric sequential field, filled for certain rows only, to an existing entity. When inserting a new row, based on a certain condition, I need to set the new field to <code>its highest value + 1</code> or to <code>NULL</code>.</p>
  
  <p>For example:</p>
  
  <pre><code>ID     NEW_FIELD     DESCRIPTION
  --------------------------------
  1          1           bla bla
  2                      bla bla       &lt;--- unmatched: not needed here
  3                      bla bla       &lt;--- unmatched: not needed here
  4          2           bla bla
  5          3           bla bla
  6          4           bla bla
  7                      bla bla       &lt;--- unmatched: not needed here
  8          5           bla bla
  9                      bla bla       &lt;--- unmatched: not needed here
  10         6           bla bla
  </code></pre>
  
  <p>In the good old SQL, it would be something like: </p>
  
  <pre class="lang-sql prettyprint-override"><code>INSERT INTO myTable (
      id, 
      new_field, 
      description
  ) VALUES (
      myIdSequence.nextVal, 
      (CASE myCondition
          WHEN true 
          THEN myNewFieldSequence.nextVal
          ELSE NULL
      END),
      'Lorem Ipsum and so on....'
  )
  </code></pre>
  
  <p>But I've no clue on how to achieve it with JPA 2.</p>
  
  <p>I know I can define callbacks methods, but <a href="http://download.oracle.com/otndocs/jcp/persistence-2.0-fr-eval-oth-JSpec/" rel="nofollow noreferrer">JSR-000317 Persistence Specification for Eval 2.0 Eval</a> discourages some specific operations from inside it:</p>
  
  <blockquote>
    <p><strong> 3.5 Entity Listeners and Callback Methods</strong><br/>
    <sub> - Lifecycle callbacks can invoke JNDI, JDBC, JMS, and enterprise beans. </sub><br/>
    <sub> - In general, the lifecycle method of a portable application <strong>should not invoke EntityManager or Query operations, access other entity
    instances, or modify relationships within the same persistence
    context</strong>.<sup>[43]</sup> A lifecycle callback method may modify the
    non-relationship state of the entity on which it is invoked.</sub></p>
    
    <p><sup>[43]</sup> <sub>The semantics of such operations may be standardized
    in a future release of this specification.</sub></p>
  </blockquote>
  
  <p>Summarizing, yes to JDBC (!) and EJB, no to EntityManager and other Entities.</p>
  
  <hr>
  
  <h1>EDIT</h1>
  
  <p>I'm trying to achieve the solution described in the answer from @anttix, but I'm encoutering some problem, so please correct me where I'm wrong.</p>
  
  <p><strong>Table</strong></p>
  
  <pre><code>MyTable
  -------------------------
  ID            number (PK)
  NEW_FIELD     number
  DESCRIPTION   text
  </code></pre>
  
  <p><strong>Main Entity</strong></p>
  
  <pre><code>@Entity
  @Table(name="MyTable")
  public class MyEntity implements Serializable {
  
      @Id
      @SequenceGenerator(name="seq_id", sequenceName="seq_id", allocationSize=1)
      @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="seq_id")
      private Long id;
  
      @OneToOne(cascade= CascadeType.PERSIST) 
      private FooSequence newField;
  
      private String description
  
      /* Getters and Setters */
  }
  </code></pre>
  
  <p><strong>Sub entity</strong></p>
  
  <pre><code>@Entity
  public class FooSequence {
  
      @Id
      @SequenceGenerator(name="seq_foo", sequenceName="seq_foo", allocationSize=1)
      @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="seq_foo")
      private Long value;
  
      /* Getter and Setter */
  }
  </code></pre>
  
  <p><strong>DAO</strong></p>
  
  <pre><code>myEntity.setNewField(new FooSequence());
  entityManager.persist(myEntity);
  </code></pre>
  
  <p><strong>Exception</strong></p>
  
  <blockquote>
    <p>Caused by: javax.transaction.RollbackException: ARJUNA016053: Could not commit transaction.</p>
    
    <p>[...]</p>
    
    <p>Caused by: javax.persistence.PersistenceException: org.hibernate.exception.SQLGrammarException: ERROR: relation "new_field" does not exist</p>
    
    <p>[...]</p>
    
    <p>Caused by: org.hibernate.exception.SQLGrammarException: ERROR: relation "new_field" does not exist</p>
    
    <p>[...]</p>
    
    <p>Caused by: org.postgresql.util.PSQLException: ERROR: relation "new_field" does not exist</p>
  </blockquote>
  
  <p>What am I doing wrong ? I'm pretty new to JPA 2 and I've never used an entity not associated to a physical table... this approach is totally new to me. </p>
  
  <p>I guess I need to put the <code>@Column</code> definition somewhere: how could JPA possibly know that the <code>newField</code> column (mapped through <a href="https://stackoverflow.com/a/19454829/1654265">ImprovedNamingStrategy</a> to <code>new_field</code> on the database) is retrieved through the <code>value</code> property of the <code>FooSequence</code> entity ?</p>
  
  <p>Some pieces of the puzzle are missing.</p>
  
  <hr>
  
  <p><strong>EDIT</strong> </p>
  
  <p>As asked in comments, this is the <code>persistence.xml</code>:</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
  &lt;persistence version="2.0" 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
                       http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"&gt;
  
      &lt;persistence-unit name="MyService"  transaction-type="JTA"&gt;
  
          &lt;jta-data-source&gt;java:jboss/datasources/myDS&lt;/jta-data-source&gt;      
  
          &lt;properties&gt;             
  
              &lt;property name="hibernate.dialect" 
                       value="org.hibernate.dialect.PostgreSQLDialect" /&gt;
  
              &lt;property name="hibernate.ejb.naming_strategy" 
                       value="org.hibernate.cfg.ImprovedNamingStrategy"/&gt;
  
              &lt;property name="hibernate.query.substitutions" 
                       value="true 'Y', false 'N'"/&gt;           
  
           &lt;property name="hibernate.show_sql" value="true" /&gt;
           &lt;property name="format_sql"         value="true" /&gt;
           &lt;property name="use_sql_comments"   value="true" /&gt;
  
          &lt;/properties&gt;
  
      &lt;/persistence-unit&gt;
  &lt;/persistence&gt;
  </code></pre>