在扩展持久化上下文中更新实体

时间:2013-04-27 09:27:02

标签: jpa ejb-3.0 seam

我有一个表单 - 工作流,其中有wfName,assignedUser,dueDate,turnAroundTime等字段。等

它由实体工作流支持,其中对用户实体的引用为多对一。

如果对assignedUser字段进行了更改(它是电子邮件地址)并且提交了表单,则会在USER实体上收到唯一约束违规错误。

我不是想要实现这一目标。我只想替换工作流实体中的用户。

save函数由有状态会话bean执行,具有EXTENDED持久化上下文。

我在这里遗漏了什么吗?这是在引用字段中更新信息的正确方法吗?

在设置我正在进行的更新用户时

User user = workflow.getUser();
//This user has its email address changed on the screen so getting a fresh reference of the new user from the database.
user = entitManager.createQuer("from User where email_address=:email_address").setParameter("email_address", user.getEmailAddress).getSingleResult();
//This new found user is then put back into the Workflow entity.
workflow.setUser(user);
entityManager.merge(workflow);

执行这些行时没有抛出异常,但是在日志后面我发现它抛出了

Caused by: java.sql.SQLException: ORA-00001: unique constraint (PROJ.UK_USER_ID) violated

实体中没有级联配置。

以下是实体的关联代码─ 工作流程 - 用户关系

    @ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "USER_ID", nullable = false)
@NotNull
public GwpsUser getUser() {
    return user;
}

public void setUserByUserId(User user) {
    this.user = user;
}

用户 - 工作流程关系

@OneToMany(fetch = FetchType.LAZY, mappedBy = "User")
public Set<Workflow> getWorkflowsForUserId() {
    return workflowsForUserId;
}

public void setWorkflowsForUserId(
        final Set<Workflow> WorkflowsForUserId) {
    this.workflowsForUserId = workflowsForUserId;
}

在SFSB中,我有两个方法loadWorkflow()和saveWorkflow()。

    @Begin(join = true)
    @Transactional
    public boolean loadProofData(){

//Loading the DataModel here and the conversation starts
}

如果我在@Begin中添加flushMode = FlushModeType.MANUAL。 saveWorkflow()方法仅在第一次正确保存数据。我必须去别的地方然后回到这个页面,如果我想进行任何进一步的改变。

saveWorkflow()方法看起来像

@SuppressWarnings("unchecked")
    public boolean saveWorkflow() throws FileTransferException {
//Do some other validations
for (Workflow currentWorkflow : workflowData) {
    User user = currentWorkflow.getUser();
//This user has its email address changed on the screen so getting a fresh reference of the new user from the database.
user = entitManager.createQuery("from User where email_address=:email_address").setParameter("email_address", user.getEmailAddress).getSingleResult();
//This new found user is then put back into the Workflow entity.
currentWorkflow.setUser(user);
}
//Do some other things
}

此处未使用merge()方法,但问题仍然存在。

1 个答案:

答案 0 :(得分:0)

你为什么要打电话给合并?工作流是否已分离(序列化)?

如果没有分离,则不应调用merge,只需更改对象即可更新。

你应该有一个setUser方法,而不是setUserByUserId?不确定这是如何工作的,也许包括你的完整代码。你的get / set方法可能会破坏你的对象,一般来说,注释字段而不是方法更安全,以避免你的get / set方法中的代码导致奇怪的副作用。

确保您没有创建该对象的两个副本,似乎您的合并以某种方式执行此操作。启用日志记录并包含SQL。合并后直接调用flush()会导致任何错误立即引发。