保留在@PostConstruct中:javax.persistence.TransactionRequiredException [英] Persisting in @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屋!