保留在@PostConstruct中:javax.persistence.TransactionRequiredException [英] Persisting in @PostConstruct: javax.persistence.TransactionRequiredException

查看:97
本文介绍了保留在@PostConstruct中:javax.persistence.TransactionRequiredException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在@PostConstruct中保留对象时,我的Entitymanager没有事务. 我不知道为什么以及如何解决这个问题,有人可以帮助我吗?

My Entitymanager has no transaction when persisting an object in @PostConstruct. I have no clue why and how to fix this, can anyone help me?

PS.如果您需要其他数据,请询问

PS. If you need any other data, please ask

TestmachineManager

@Singleton
public class TestmachineManager {
    @PersistenceContext
    private EntityManager em;

    private TimerTask handler = new TimerTask() {
        @Override
        public void run() {
            DayPlanning planning = getPlanning();
            Order order = planning.getNextInLine();
            if(order instanceof Order) {
                em.merge(planning);
                List<String> tests = new ArrayList();
                for(Test test : order.getTests()) {
                    tests.add(test.getName());
                }

                TestmachineSender.orderTests(order.getId(), order.getDomain(), tests);
                timer.schedule(checker, safetycheckAt());
            }
            else {
                timer.schedule(handler, postponeTo());
            }
        }
    };

    @PostConstruct
    public void init() {
        if(getPlanning().hasActiveTest()) {
            handler.run();
        }
    }

    private DayPlanning getPlanning() {
        LocalDate today = new LocalDate(
                Calendar.getInstance().getTime());

        try {
            CriteriaBuilder cb = em.getCriteriaBuilder();
            CriteriaQuery<DayPlanning> query = cb.createQuery(DayPlanning.class);
            Root dayPlanning = query.from(DayPlanning.class);
            Predicate predicateDate = cb.equal(dayPlanning.get("dateOfPlanning"), today.toDate());

            query.select(dayPlanning).where(predicateDate);
            return em.createQuery(query).getSingleResult();
        } catch(NoResultException ex) {
            DayPlanning newPlanning = new DayPlanning(today);
            em.persist(newPlanning);
            return newPlanning;
        }
    }
}

Stacktrace

Caused by: javax.persistence.TransactionRequiredException
    at com.sun.enterprise.container.common.impl.EntityManagerWrapper.doTxRequiredCheck(EntityManagerWrapper.java:163)
    at com.sun.enterprise.container.common.impl.EntityManagerWrapper.doTransactionScopedTxCheck(EntityManagerWrapper.java:145)
    at com.sun.enterprise.container.common.impl.EntityManagerWrapper.persist(EntityManagerWrapper.java:263)
    at TestmachineManager.getPlanning(TestmachineManager.java:130)
    at TestmachineManager.init(TestmachineManager.java:78)

推荐答案

您在@PostConstruct中有一个Singleton bean事务.丢失交易的时刻是使用timer.schedule(checker, safetycheckAt());timer.schedule(handler, postponeTo());启动新计时器的时候.我认为您正在使用的计时器对象实际上是java.util.Timer,正在查看签名.

You have a transaction in @PostConstruct for the Singleton bean. The moment you are loosing your transaction is when you launch a new timer using timer.schedule(checker, safetycheckAt()); or timer.schedule(handler, postponeTo());. I think that the timer object that you are using is actually java.util.Timer, looking at the signature.

您应该尝试使用EJB TimerService资源.例如:

You should try using the EJB TimerService resource. For example:

@Resource
private TimerService timerService;

@Timeout
public void run() {
    DayPlanning planning = getPlanning();
    Order order = planning.getNextInLine();
    if(order instanceof Order) {
        em.merge(planning);
        List<String> tests = new ArrayList();
        for(Test test : order.getTests()) {
            tests.add(test.getName());
        }

        TestmachineSender.orderTests(order.getId(), order.getDomain(), tests);

        // if the checker handler doesn't need to run transactionally you could leave it like it was before
        timer.schedule(checker, safetycheckAt());
        // otherwise you could create a checker EJB that uses @Timeout in the same manner or @Scheduled from EJB3.1
    } else {
        // postpone timer
        timerService.createTimer(postponeTo(), "postponed timer information");    
    }
}

@PostConstruct
public void init() {
    if(getPlanning().hasActiveTest()) {
        timerService.createTimer(computeDelay(), "timer information");
        // or you could use the other create methods of the timerService, those that fits your needs better
    }
}

我没有测试代码,这只是粗糙的代码.希望对您有所帮助.

I didn't tested the code, it's just rough code. Hope it helps.

这篇关于保留在@PostConstruct中:javax.persistence.TransactionRequiredException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆