【发布时间】:2015-05-05 15:10:29
【问题描述】:
我正在从事主要使用 EJB 和 JPA 的项目,但我遇到了不应发生的 ConstraintViolationException 问题。
首先,我有 MyEntity 类,其中 @Id 和几个唯一字段。
我有@Stateless MyEntityRepository 类和find() 方法,它只是通过调用EntityManager get() 方法返回MyEntity(或null)。
另一个@Stateless bean 是SaveEntityBean:
@Stateless
public class SaveEntityBean {
@Inject
EntityManager em;
@Inject
MyEntityRepository repository;
public void saveEntity(MyEntity me) {
if(repository.find(me) == null) {
//the place with ConstraintViolationException
em.persist(me);
}
}
public void saveEntities(List<...> entities) {
for(MyEntity me: entities)
saveEntity(e);
}
}
并且方法saveEntities(List<...> entities)是从另一个bean调用的:
@Stateless
@Startup
public class SaveEntityBean {
@Inject
SaveEntityBean saveBean;
//...
@Schedule(hour = "*", minute = "*", second="*/5")
@AccessTimeout(unit = TimeUnit.MINUTES, value = 1)
public void mainLogicMethod() {
List<MyEntity> entities = io.calculateAndGetEntities();
saveBean.saveEntities(entities);
}
}
io.calculateAndGetEntities() 方法是长 IO 工作。问题是有时我会得到org.hibernate.exception.ConstraintViolationException,我认为这不应该发生,因为我在调用persist() 方法之前检查了MyEntityRepository.find(me) != null 条件。
我唯一的想法是提交之间有一些延迟,所以在条件检查中调用MyEntityRepository.find(me)方法后,提交发生,然后persist()方法抛出异常。
请给我任何建议阅读和学习什么以及如何解决问题。
编辑: 我发现这是线程的问题,所以解决方案可能是锁定写/读。
【问题讨论】:
-
确实它看起来像一个同步问题 - 你在 saveEntity() 中有一个检查然后执行操作,而 mainLogicMethod() 计时器产生线程。
-
当我发现变量 me 和 em 在同一个范围内时,我停止了阅读。