Я думаю, у меня есть решение этой проблемы. Моя проблема была также в том, что таймер был удален, если произошли ошибки EJB / JPA.
Я только что попытался решить эту проблему с событиями CDI, потому что я хотел, чтобы Исключение могло быть выброшено в другом месте, чтобы @Schedule
не трогали. Я думал, что использование событий cdi будет отделить @Schedule
от startSomeEvent
-Metod. Это не. (Я не знаю, почему программирование иногда является наукой о каменном веке) Но трюк делает @Asynchronous
-аннотацию на startSomeEvent
-методе.
Итак, я реализовал @Singleton
TimerService
, который используется для всех таймеров, которые есть в моем приложении:
@Singleton
public class TimerService implements Serializable {
@Inject
private Event<SomeEvent> someEvent;
@Schedule(hour = "*", second = "0", minute = "*", persistent = false)
public void fireSomeEvent() {
someEvent.fire(new SomeEvent());
}
}
Событие SomeEvent
наблюдается методом, который фактически выполняет то, что вам нужно. Вот в примере это создает Person
с username
. username
равно UNIQUE
, поэтому во второй раз, когда событие запускается, выдается MySQLIntegrityConstraintViolationException: Duplicate entry 'uniqueUsername' for key 'USERNAME'
. Это убило бы нашу @Schedule
, но это не так, потому что у нас есть @Asynchronous
-аннотация.
@Singleton
public class TimerTestService {
@PersistenceContext(unitName = "VWMam3PU")
private EntityManager entityManager;
@Asynchronous
public void startSomeEvent(@Observes SomeEvent event) {
Person p = new Person();
p.setUsername("uniqueUsername");
entityManager.persist(p);
}
}
Класс SomeEvent
- это простой POJO:
public class SomeEvent {
}
Итак, я долго искал решение этой проблемы. Теперь это работает для меня. Он запускает исключение и пытается это снова, снова и снова.