【问题标题】:Resetting value of p:inputText in p:inplace when DB constraint validation failed当 DB 约束验证失败时,在 p:inplace 中重置 p:inputText 的值
【发布时间】:2012-10-15 09:40:11
【问题描述】:

我有这个代码:

<p:inplace id="staffno" editor="true">
                    <p:ajax event="save" listener="#{staffbean.onSave}" update="staffnoInplace messages" />                    
                    <p:inputText id="staffnoInplace" value="#{staffbean.vieweditStaff.staffno}"/>                                                 
</p:inplace>  

在 staffbean.onSave() 中,我通过 JPA/Hibernate 存储它。在它成功的情况下,我没有遇到任何问题。它存储在数据库中。

我的问题与 Hibernate 由于 DB 限制引发异常的情况有关。在这些情况下,我希望原地保持可编辑状态并且不更改值。目前,它在数据库级别失败,但我仍然看到 UI 对象上的值更改为不正确的值。

【问题讨论】:

    标签: java jsf primefaces


    【解决方案1】:

    您应该为inputText 组件包含一个验证方法或验证器,以便在数据库中已经存在给定ID 时反转bean 值并防止onSave 事件的执行。

    故意尝试将记录插入数据库,希望数据库约束提供验证,这是一种模糊的数据安全实践。我并不是说数据库约束不好,我只是说您应该在尝试插入数据库之前尽一切努力验证和清理您的输入。

    在您的托管 bean 中包含一个验证方法,如下所示:

    public void validateStaffNoId(FacesContext context, UIComponent component, Object value)
            throws ValidatorException {
        //Query DB to see if ID exists...
        if (idExists()) {
            //Throw validator exception
        }
    }
    

    然后在你的 inputText 组件中简单地添加属性:

    <p:inputText ... validator="#{staffBean.validateStaffNoId}" ... />
    

    【讨论】:

    • 我曾希望避免这种情况,因为这意味着我必须执行额外的 DB 查询来验证实体的存在。还有其他方法吗?我可以用其他方式反转 bean 吗?为什么依赖约束异常不好?
    • @javaMS is it bad to rely on constraint exceptions? 这是一个非常好的问题,至今仍在争论。见这里:programmers.stackexchange.com/questions/76052/…
    • @javaMS 对于 JSF,存在验证阶段,整个框架将根据应用程序验证处理应用和回滚值。 JSF 鼓励这种模式,所以不管你对这个主题有什么感觉,最好这样做。另一点是,一些数据库通过强制引用完整性比获取单个记录的性能更差。如果表被正确索引,预取这条记录的性能损失应该是最小的。
    • 我完全相信你所说的,但我仍然不喜欢有两个查询的设计,因为我可以用一个来解决它。你的第二点很有说服力。但是,为了符合框架,我可以在异常处理中手动验证失败吗?我尝试使用 FacesContext.getCurrentInstance().validationFailed(); FacesContext.getCurrentInstance().renderResponse();但它只完成了一半的工作,即使该字段处于可编辑模式并为我提供错误消息。它不允许任何进一步的操作,并且取消按钮不起作用。
    • 实际上捕获异常可能更可取的另一个原因是:并发性。如果有两个客户端 C1 和 C2 尝试写入 DB,如果我仅依赖应用程序代码,那么可能是 C1 尝试写入时应用的第一个查询(检查查询)将返回“未找到记录”,但是C2 在检查之后立即写入,但在 C1 设法写入 DB 之前。
    猜你喜欢
    • 2021-03-10
    • 2015-05-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多