编辑行并验证

时间:2013-06-29 15:23:02

标签: java validation jsf ejb

我想在数据表中编辑我的行,但是我遇到了问题。我有一个验证器,用于检查数据库中是否有社会安全号码。当我添加一切都没问题。我正在编辑时出现问题。 以下是我的编辑页面中的代码片段:

<h:form>
    <div id="userPanel">
        <p:panel id="panelUser" header="Edytuj administratora" >
            <div id="panelImage">
                <img src="./../../images/person4.png" alt="person" width="150px" height="130px"/>
            </div>
            <h:inputHidden value="#{userMB.user.id}" />
            <h:panelGrid columns="3">
                <p:outputLabel for="firstName" value="#{msg.firstName}"></p:outputLabel>
                <p:inputText id="firstName" value="#{userMB.user.firstName}" label="#{msg.firstName}" required="true">
                    <f:validator validatorId="firstNameValidator" />  
                    <p:ajax update="msgFristName" event="keyup" />  
                </p:inputText>  
                <p:message for="firstName" id="msgFristName"/> 

                <p:outputLabel for="lastName" value="#{msg.lastName}"></p:outputLabel>
                <p:inputText id="lastName" value="#{userMB.user.lastName}" label="#{msg.lastName}" required="true">
                    <f:validator validatorId="lastNameValidator" />   
                    <p:ajax update="msgLastName" event="keyup" /> 
                </p:inputText>  
                <p:message for="lastName" id="msgLastName"/> 

                <p:outputLabel for="personalId" value="#{msg.personalId}"></p:outputLabel>
                <p:inputText id="personalId" value="#{userMB.user.personalId}" label="#{msg.personalId}" required="true">
                    <f:validator binding="#{personalIdValidator}" />   
                    <p:ajax update="msgPersonalId" event="keyup" /> 
                </p:inputText>  
                <p:message for="personalId" id="msgPersonalId"/>

                <p:outputLabel for="password" value="#{msg.password}"></p:outputLabel>
                <p:inputText id="password" value="#{userMB.user.password}" label="#{msg.password}" required="true">
                    <f:validator validatorId="passwordValidator" />   
                    <f:attribute name="confirmPassword" value="#{confirmPassword}" />
                    <p:ajax update="msgPassword" event="keyup" /> 
                </p:inputText>  
                <p:message for="password" id="msgPassword"/>

                <p:outputLabel for="confirmPassword" value="#{msg.confirmPassword}"></p:outputLabel>
                <p:inputText id="confirmPassword" binding="#{confirmPassword}" label="#{msg.confirmPassword}" required="true">
                    <f:validator validatorId="passwordValidator" />   
                    <f:attribute name="confirmPassword" value="#{confirmPassword}" />
                    <p:ajax update="msgConfirmPassword" event="keyup" /> 
                </p:inputText>  
                <p:message for="confirmPassword" id="msgConfirmPassword"/>
            </h:panelGrid>
            <center><p:commandButton value="#{msg.edit}" action="#{userMB.editUser()}" ajax="false">
                    <f:param name="userRole" value="admin" />
                    <f:param name="active" value="true" />
                </p:commandButton>
                <p:commandButton value="#{msg.cancel}" action="#{userMB.cancel()}" ajax="false" immediate="true"/></center>
        </p:panel>
    </div>
</h:form>

当我想编辑用户时,我点击按钮:

<center><p:commandButton value="#{msg.edit}" action="#{userMB.editUser()}" ajax="false">

调用方法editUser

public String editUser() {
    FacesContext context = FacesContext.getCurrentInstance();
    Map requestParameterMap = (Map) context.getExternalContext().getRequestParameterMap();
    try {
        String userRole = requestParameterMap.get("userRole").toString();
        String active = requestParameterMap.get("active").toString();
        Boolean act = Boolean.parseBoolean(active);
        user.setRole(userRole);
        user.setActive(act);
        if ((user.getEmail() != null) && (userDao.findEmailExist(user.getEmail()))) {
            sendErrorMessageToUser("Użytkownik z podanym adresem email istnieje w bazie");
            return null;
        } else if ((user.getPersonalId() != null) && (userDao.findPersonalIdExist(user.getPersonalId()))) {
            sendErrorMessageToUser("Użytkownik z podanym numerem pesel istnieje w bazie");
            return null;
        } else if ((user.getPhone() != null) && (userDao.findPhoneExist(user.getPhone()))) {
            sendErrorMessageToUser("Użytkownik z podanym numerem telefonu istnieje w bazie");
            return null;
        } else {
            userDao.update(user);
        }
    } catch (EJBException e) {
        sendErrorMessageToUser("Błąd edycji użytkownika w bazie");
        return null;
    }
    sendInfoMessageToUser("Konto zedytowane");
    return user.getRole() + "List";
}

方法find personalIdExist在编辑过程中找到personalId时返回true,如果没有找到则返回false。

这是我的问题。在我编辑User时,我的编辑页面看起来像这样: 例如:

firstName:Pablo

lastName:ABCD

personalId:12345678901

密码:zxcv

当我编辑我的个人ID时,一切正常,但我只能编辑firstNamelastNamepassword而不是personalIdPersonalId可能是相同的。当我点击编辑时出现问题,因为我的方法personalIdExist会返回true,如果该ID已存在且我无法更新我的用户。 我需要一个地方来保存初始值personalId这个用户能够编辑它。但不知道如何。

2 个答案:

答案 0 :(得分:2)

据我所知,检查数据库中是否有重复的id是持久层的一部分,你不应该尝试在Validator中验证它。

使用验证程序检查更多正式问题(数据格式,所需数据丢失等)。重复id的问题应该由业务逻辑控制或委托给持久层;那将是没有问题的,因为您将知道该操作是添加新用户还是修改现有用户。

如果您坚持使用验证器,请为每个问题创建一个特定验证器(更新personal或创建personal

更新:我想我知道你想要什么。你希望在每个字符添加到id之后,如果数据库已经存在或不存在,它将被验证,并显示一条消息,如果它已经存在,不是吗?但有时候检查应该是一个错误(因为它引入了重复),而在其他情况下则不应该(因为它正在查找数字)。我是对的吗?

在这种情况下,我会说你有两种不同的用法,你应该使用两种不同的属性(newPersonalIdeditedPersonalId),而不是试图混合它们。

另一种方法可能是在bean中创建一个exists布尔属性;设置personalId会导致查找继续进行,如果已经在数据库中,则exists属性将设置为true。在XHTML中,一些元素将基于此呈现/禁用;但这对我来说太复杂了。

UPDATE2:我仍然不明白,如果用户已经存在,您正积极阻止更新数据库,使用此代码

    } else if ((user.getPersonalId() != null) && (userDao.findPersonalIdExist(user.getPersonalId()))) {
        sendErrorMessageToUser("Użytkownik z podanym numerem pesel istnieje w bazie");
        return null;

持久层非常简单,请记住,在此阶段user分离实体,因此您需要使用EntityManager.merge方法。

答案 1 :(得分:1)

这是我对你的问题的解释。

当您通过更改所有内容编辑用户时,但您会收到个人错误

SJuan76方法是正确的。您不希望验证器为您进行检查。相反,只需专注于确保用户像您期望的那样为personlId输入值。然后,使持久层为您强制执行唯一性(不需要编写自己的逻辑)。我假设你正在使用ORM(但我不确定哪一个)所以你的UserMB应该看起来像这样(伪代码,因为我正在写下我的头脑)。

public class UserMB {

    private Long personalId; //Not sure what your actual type is 

    @Column(unique = true)//Uniqueness constraint
    public Long getPersonalId() { 
        return personalId; 
    }

    //Remainder omitted
}

如果您使用的是纯SQL或某些变体,请确保在创建表时为personalId列声明该唯一性约束。在这两种情况下,当您尝试更新UserMB personalId并且其他人已经拥有它时,将抛出异常。只需捕获它并将其作为错误消息返回。

通过此更改,您将不再需要在您的编码中使用以下方法

findPersonalIdExist(user.getPersonalId())

(顺便说一句,这是问题的根本原因)如果您尝试更新firstNamelastName 而不更改{{1}一切都会顺利进行。如果您尝试编辑personalId ID并且其他人已经拥有该ID,则不会允许更新。

评论

这与你的具体问题无关,但我有点担心你的逻辑。您已经拥有下面的用户ID(我猜这是您的ORM正在管理的用户ID)。

personal

因此,您不应该通过将值作为参数传递来查找是否存在列(例如phoneNumber)。您应该根据来自数据库的唯一<h:inputHidden value="#{userMB.user.id}" /> 直接获取用户实例,并验证他是否只是重新输入相同的信息。你可能会遇到问题。这是一个场景:

userA想要将电话号码从123更改为345

userB已有电话号码345

即使用户A没有输入相同的值,您的代码也会返回true(除非这是您想要的)。如果您确实希望每个人都拥有其字段的唯一值,只需在需要的位置添加id即可。不需要所有这些检查。

您还可以通过提供自己的转换器或在unique="true"中设置一些参数来消除所有null检查,以便将所有提交的空字符串解释为faces-config。请参阅以下链接

h:inputText which is bound to String property is submitting empty string instead of null