我试图通过使用EXTENDED_PERSISTENT_CONTEXT来维护多个呼叫状态。 我的理解是,管理机构将不经过我以前抛出验证错误,但是我不断收到电话中涉及到分离的实体错误调用之间分离。 状态维持在一个有状态会话bean:
@Named(SessionFacadeBean.SEAM_NAME)
@SessionScoped
@Stateful
@LocalBean
@AccessTimeout(value = 10, unit = TimeUnit.SECONDS)
public class SessionFacadeBean implements Serializable
{
public static final String SEAM_NAME = "sessionCacheBean";
@PersistenceContext(unitName = GlobalParameters.BACKEND_CODE_PERSISTENCE_CONTEXT_NAME, type = PersistenceContextType.EXTENDED)
private EntityManager em;
private ParentOne sessionData;
public synchronized ParentOne getSessionData() {
if(sessionData == null) {
sessionData = new ChildTwo();
}
return sessionData;
}
public boolean getLock() {
return true;
}
public void clearLock() {
}
// Other stuff I don’t ‘think’ is relevant.
}
的(简化的)状态被使用休眠存储。 它由三个班(父母和两个孩子,其中一个包含孩子的清单):
@XmlRootElement(name = XMLConstants.COMPONENT_ELEMENT_NAME_IN_XML)
@XmlAccessorType(XmlAccessType.NONE)
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "Class", length = 50)
@Entity
public class ParentOne
{
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@XmlElement(name = "ID")
private Long iD;
@XmlElement(name = "name")
protected String friendlyName = "";
}
@XmlRootElement(name = XMLConstants.COMPONENT_ELEMENT_NAME_IN_XML)
@XmlAccessorType(XmlAccessType.NONE)
@Entity
public class ChildOne extends ParentOne
{
public ChildOne(String name, ParentOne child) {
super(name);
myChild = child;
}
@ManyToOne(cascade = CascadeType.ALL)
protected ParentOne myChild;
}
@XmlRootElement(name = XMLConstants.COMPONENT_ELEMENT_NAME_IN_XML)
@XmlAccessorType(XmlAccessType.NONE)
@Entity
public class ChildTwo extends ParentOne
{
public ChildTwo() {
super(“common”);
}
}
我是从一个无状态的bean像这样访问状态bean:
@Stateless
@LocalBean
@Path("/")
public class MyService
{
@PersistenceContext(unitName = GlobalParameters.BACKEND_CODE_PERSISTENCE_CONTEXT_NAME)
private EntityManager em;
@Inject
private SessionFacadeBean sessionBean;
@POST
@Path("/create/item")
@ValidateRequest
public ComponentShortSummary addItem(@Form NewItemForm itemForm)
{
if(sessionBean.getLock()) {
try {
if(itemForm.getName().equals("INVALID") == true) {
throw new ConstraintViolationException("Failed", new HashSet<ConstraintViolation<?>>());
}
ChildOne child = new ChildOne(itemForm.getName(), sessionBean.getSessionData());
em.persist(child);
return null;
}
finally {
sessionBean.clearLock();
}
} else {
return null;
}
}
}
若要重现该问题,我执行顺序如下:
- 打电话的addItem使用有效名称(这种情况继续下去的项目数据库)。
- 打电话的addItem与“无效”的名称,这将引发约束例外。
- 打电话的addItem使用有效名称(这会导致一个分离的实体错误就行了
em.persist(child)
。
我不明白的是如何/为什么我结束了与分离的实体。 在实际的代码,我会进行一些请求/状态验证,修改前的状态(所以没有任何理由,我可以看到已经被拆下)。
如果我删除调用sessionBean.getLock()
然后问题消失(对象坚持正确)。 的锁方法的目的本质上是串行访问会话状态,但目前getLock()
方法是空的,感觉这个问题可能与这样的事实,我打电话到状态bean抛出异常之前。
任何人能解释这是怎么回事,在我的实体结果上脱离/如果有一种方法,以避免它(理想在支持任何解释文档点我)?
虽然有可能的方式,我可以解决当前的问题,在所有访问状态bean之前执行验证,我很担心,一般情况下(有状态Bean已经在呼叫被访问后的任何异常被抛出)。 有没有被拆除,以便处理异常时,我不希望实体从扩展持久上下文中接受的策略?