Note that there are some explanatory texts on larger screens.

plurals
  1. POEntityManager.flush() commits the transaction in a Java web service
    primarykey
    data
    text
    <p><strong>EDIT</strong>: <em>Thanks everybody for your answers, but the problem was with my data source configuration, which was actually in auto-commit mode. See <a href="https://stackoverflow.com/a/13442550/89435">my answer below</a> for details.</em></p> <p>Both the Javadoc of the <a href="http://docs.oracle.com/javaee/6/api/javax/persistence/EntityManager.html#flush%28%29" rel="nofollow noreferrer">EntityManager.flush()</a> method and searching for it in Google seem to suggest that the <code>flush</code> method only sends the pending statements to the database and does not commit the transaction. But a simple test web service I created (in Java 7, Oracle 11gR2, JBoss 7.1 and the Web service is packaged as a jar file) seem to indicate otherwise:</p> <p>This is the table creation script:</p> <pre><code>CREATE TABLE test( id INTEGER NOT NULL, name VARCHAR2(20), CONSTRAINT test_pk PRIMARY KEY ("ID") ); CREATE SEQUENCE test_seq; </code></pre> <p>This is the corresponding entity:</p> <pre><code>@Entity @Table(name = "TEST") public class Test implements Serializable { private static final long serialVersionUID = 9192814682033048425L; @Id @Column(name = "ID") @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "TEST_SEQ") @SequenceGenerator(name="TEST_SEQ",sequenceName="TEST_SEQ", allocationSize = 1) private Integer id; @Column(name = "NAME") private String name; // Getters and setters... } </code></pre> <p>And the test web service:</p> <pre><code>@Stateless @WebService(serviceName = "TestService") @TransactionManagement(TransactionManagementType.CONTAINER) public class TestServiceBean implements TestService { @PersistenceContext private EntityManager entityManager; @Override public void createTest(String name) { Test test = new Test(); test.setName(name); entityManager.persist(test); entityManager.flush(); throw new RuntimeException(); } } </code></pre> <p>My understanding is that:</p> <ul> <li>When the <code>createTest</code> method is called, the application starts a new transaction</li> <li>The <code>persist()</code> method generates an INSERT statement to be sent to the database</li> <li>The <code>flush()</code> method sends the INSERT statement to the database <strong>but does not commit the transaction!</strong></li> <li>The RuntimeException causes the transaction to rollback.</li> </ul> <p>But obviously my understanding is wrong: every time I run the web service method I get one new row in the table. Moreover, stepping into this method with a debugger reveals that the row is inserted when the <code>flush()</code> method is called (I can "see" the row from another db session using SQL Developer).</p> <p>Can someone please explain this behavior?</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload