2

I have an EJB with a @Schedule marked method, that persists an entity to a database. Within this method, when I'm calling EntityManager.flush() after persist(), I'm getting javax.persistence.TransactionRequiredException: No transaction is currently active

AFAIK all EJB methods are transactional, but I'm getting this error even if I additionally mark the method with @TransactionAttribute(REQUIRED).

When I manage a transaction manually by EntityTransaction.begin() and commit(), everything works OK.

I'm using Wildfly 10.0 Final on JDK 8u74, EclipseLink 2.6.0.

Here is my persistence.xml:

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence" version="2.1">    
    <persistence-unit name="mainPU" transaction-type="JTA">
        <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
        <jta-data-source>java:/datasources/ExampleDS</jta-data-source>
        <class>com.example.MyEntity</class>
    </persistence-unit>    
</persistence>

MyEJB.java:

package com.example;

import javax.ejb.*;
import javax.ejb.Timer;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

@Startup
@DependsOn("AppUtils")
@Singleton
public class MyEJB {
    @PersistenceContext(unitName = "mainPU")
    private EntityManager em;

    @Schedule(hour = "*", minute = "*", second = "*/20", info = "", persistent = false)
    private void doStuff(Timer timer) {
        MyEntity entity = new MyEntity("Test" + Math.random(), "Test value");
        em.merge(entity);
        em.flush();
    }
}
Ultranium
  • 332
  • 2
  • 19
  • 1
    Is `doStuff` really a private method? If so it's unlikely to be invoked correctly, if at all. – Steve C Feb 08 '16 at 01:19
  • 2
    Yes, doStuff is a private method and it invokes by timer just fine. – Ultranium Apr 18 '16 at 10:57
  • 1
    You got me to double check the spec and you're right: "A timeout callback method can have public, private, protected, or package level access. A timeout call- back method must not be declared as final or static." This applies to both EJB 3.1 and 3.2. - Thanks! – Steve C Apr 18 '16 at 11:14
  • It might be an integration bug with Eclipse JPA. Does it work if you comment out the ... so that the default (Hibernate) JPA implementation is used? – Steve C Apr 18 '16 at 11:17

1 Answers1

-2

When you use JTA it commit and flush the changes into the database and close the current transaction. So, when you do em.flush(), the transaction is already closed.

  • 1
    Nope, the transaction is only committed when the method returns, not when you call ```em.merge```, otherwise exceptions will fail to rollback the transactions inside the same method – maress Feb 08 '16 at 11:40