0

データテーブルの行を編集したいのですが、問題があります。データベースに社会保障番号があるかどうかをチェックするバリデーターがあります。追加すると、すべて問題ありません。編集中に問題が発生します。以下は、編集ページのコード フラグメントです。

<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、次のようになります: 例:

名前:パブロ

姓: ABCD

個人ID: 12345678901

パスワード: zxcv

personalId を編集しているときはすべて問題ありませんが、のみ編集できfirstName、は編集できません。同じかもしれません。[編集] をクリックすると問題が発生します。ID が既に存在する場合にメソッドが返され、ユーザーを更新できないためです。このユーザーが編集できるようにするには、このユーザーの初期値 personalId を保存する場所が必要です。しかし、方法がわからない。lastNamepasswordpersonalIdPersonalIdpersonalIdExisttrue

4

2 に答える 2

2

私が理解しているように、データベースに繰り返しIDがあるかどうかを確認することは永続化レイヤーの一部であり、バリデーターでそれを確認しようとするべきではありません.

バリデーターを使用して、より正式な問題 (データの形式、必要なデータの欠落など) を確認します。ID の重複の問題は、ビジネス ロジックによって制御するか、永続化レイヤーに委譲する必要があります。操作が新しいユーザーを追加するのか、既存のユーザーを変更するのかがわかるので、問題はありません。

これにバリデーターを使用することを主張する場合は、各問題に対して特定のバリデーターを作成します (を更新するpersonalか、を作成しますpersonal) 。

更新: 私はあなたが望むものを見たと思います. 各文字が ID に追加された後、それが既に存在するかどうかデータベースに対して検証され、既に存在する場合はメッセージが表示されますね。しかし、そのチェックがエラーになる場合もあれば (重複が発生するため)、そうでない場合もあります (番号を検索しているため)。私は正しいですか?

その場合、2 つの異なる使用法があり、2 つの異なるプロパティ (newPersonalIdeditedPersonalId) を使用する必要があり、それらを混在させようとしないでください。

別のアプローチはexists、Bean にブール値のプロパティを作成することです。設定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ではDetached Entityであるため、メソッドを使用する必要があることを覚えておいてくださいEntityManager.merge

于 2013-06-29T15:40:05.750 に答える
1

これがあなたの問題の私の解釈です。

すべてを変更してユーザーを編集すると、personalId はエラーになります

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ていて、他の誰かが既にそれを持っている場合、例外がスローされます。キャッチしてエラーメッセージとして返すだけです。

この変更により、codition で次のメソッドが不要になります

findPersonalIdExist(user.getPersonalId())

(ちなみに、これが問題の根本的な原因です)更新しようとするとfirstName、すべてを変更lastName せずpersonalIdにスムーズに実行されます。自分の ID を編集しようとして、personal他の誰かがすでに ID を持っている場合、更新は許可されません。

コメント

これはあなたの具体的な問題とは関係ありませんが、私はあなたの論理に少し関心があります. あなたはすでに以下のユーザーIDを持っています(これはあなたのORMが管理しているものだと思います)。

<h:inputHidden value="#{userMB.user.id}" />

したがって、値を引数として渡して列 (例: phoneNumber) が存在するかどうかを調べようとしないでください。DB から一意に基づいてユーザーインスタンスidを直接取得し、同じ情報を再入力しているだけではないことを確認する必要があります。問題が発生する可能性があります。シナリオは次のとおりです。

ユーザーAは電話番号を123から345に変更したい

userB はすでに電話番号 345 を持っています

ユーザー A が同じ値を入力していない場合でも、コードは true を返します (それが必要な場合を除く)。全員が自分のフィールドに一意の値を持ちたい場合unique="true"は、必要な場所に追加するだけです。これらすべてのチェックは必要ありません。

独自のコンバーターを提供するか、いくつかのパラメーターを設定して、送信されたすべての空の文字列が として解釈されるようにすることで、すべてのnullチェックを排除することもできます。以下のリンクをご覧くださいfaces-confignull

h:inputText が String プロパティにバインドされているため、null ではなく空の文字列が送信されます

于 2013-06-29T20:36:26.377 に答える