65463
JavaEEにて部署管理アプリを作成しています。  
新規データ登録時に部署番号がデータベースで重複している場合、画面上にエラーメッセージを表示したいのですが、現状コードでは重複時のエラーは表示されるのですが、非重複時の新規登録でエラー画面（用意しているxhtml）に遷移してしまいます。  
原因をご教授頂けますと幸いです。

```

    <?xml version='1.0' encoding='UTF-8' ?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml"
        xmlns:f="http://xmlns.jcp.org/jsf/core"
        xmlns:h="http://xmlns.jcp.org/jsf/html"
        xmlns:ui="http://java.sun.com/jsf/facelets">
    <h:head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
        <title>部署編集</title>
        <link rel="stylesheet" type="text/css" href="/practice2016/css/practice2016.css" />
    </h:head>
    <h:body>
        <f:view>
        <div class="center">
            <div class="center">
                <h1>部署編集</h1>
            </div>
            <h:messages styleClass="facesMessage" errorClass="error" />
            <h:form>
                <div class="frame2">
                    <div class="search">
                        <div>
                            <span class="label">ID</span>
                            <span class="input1"><h:inputText value="#{editBean.id}" disabled="#{editBean.disableId}" label="ID" size="13"/></span>
                        </div>
                        <div>
                            <span class="label">部署番号</span>
                            <span class="input2"><h:inputText value="#{editBean.deptNo}" disabled="#{editBean.disableDeptNo}" maxlength="9" label="部署番号" size="13"/></span>
                        </div>
                        <div>
                            <span class="label">部署名</span>
                            <span class="input3"><h:inputText value="#{editBean.deptName}" maxlength="20" label="部署名" size="13"/></span>
                        </div>
                        <div>
                            <span class="label">場所</span>
                            <span class="input4"><h:inputText value="#{editBean.loc}" maxlength="20" label="場所" size="13"/></span>
                        </div>
                    </div>
                    <div class="search2">
                        <h:commandButton class="return" action="#{editBean.back()}" value="戻る" immediate="true"/>
                        <h:commandButton class="save" action="#{editBean.save()}" value="保存" />
                        <h:commandButton class="delete" action="#{editBean.delete()}" value="削除" onclick="return confirm('削除しますか？');"/>
                    </div>
                </div>
            </h:form>
        </div>
        </f:view>
    </h:body>
    </html>
    
```

```

    /**
     * 編集画面のバッキングBean
     */
    @Model
    @ViewScoped
    public class EditBean extends AbstractBean implements Serializable {
    
        @Inject
        private EditLogic logic;
        private Long id;
    
        @NotEmpty(message="{errors.required}")
        private String deptName;
    
        @Min(value=1)
        @NotNull(message="{errors.required}")
        private Integer deptNo;
    
        private String loc;
        private Integer versionNo;
        private boolean disableId;
        private boolean disableDeptNo;
    
        /**
         * @return id
         */
        public Long getId() {
            return id;
        }
        /**
         * @param id セットする id
         */
        public void setId(Long id) {
            this.id = id;
        }
        /**
         * @return deptName
         */
        public String getDeptName() {
            return deptName;
        }
        /**
         * @param deptName セットする deptName
         */
        public void setDeptName(String deptName) {
            this.deptName = deptName;
        }
        /**
         * @return deptNo
         */
        public Integer getDeptNo() {
            return deptNo;
        }
        /**
         * @param  セットする deptNo
         */
        public void setDeptNo(Integer deptNo) {
            this.deptNo = deptNo;
        }
        /**
         * @return loc
         */
        public String getLoc() {
            return loc;
        }
        /**
         * @param loc セットする loc
         */
        public void setLoc(String loc) {
            this.loc = loc;
        }
        /**
         * @return versionNo
         */
        public Integer getVersionNo() {
            return versionNo;
        }
        /**
         * @param versionNo セットする versionNo
         */
        public void setVersionNo(Integer versionNo) {
            this.versionNo = versionNo;
        }
        /**
         * @return disableId
         */
        public boolean isDisableId() {
            return disableId;
        }
        /**
         * @param disableId セットする disableId
         */
        public void setDisableId(boolean disableId) {
            this.disableId = disableId;
        }
        /**
         * @return disableDeptNo
         */
        public boolean isDisableDeptNo() {
            return disableDeptNo;
        }
        /**
         * @param disableDeptNo セットする disableDeptNo
         */
        public void setDisableDeptNo(boolean disableDeptNo) {
            this.disableDeptNo = disableDeptNo;
        }
    
    
        /**
         * 初期処理
         */
        @PostConstruct
        @Auth
        public void init(){
            if(FlashUtil.get("id") != null){
                this.setId(Long.valueOf(FlashUtil.get("id")));
                logic.init(this);
            }
        }
    
        /**
         * 戻るボタン押下時処理
         * @return 遷移先画面
         */
        @Auth
        public String back(){
            // 検索画面に戻る
            return "/views/dept/search/index.xhtml?faces-redirect=true";
        }
    
        /**
         * 保存ボタン押下時処理
         * @return 遷移先画面
         */
        @Auth
        public String save(){
            logic.save(this);
            return null;
        }
    
        /**
         * 削除ボタン押下時処理
         * @param id
         * @return 遷移先画面
         */
        @Auth
        public String delete(){
            logic.delete(this);
            return back();
        }
    }
    
```

```

    /**
     * 編集画面のビジネスロジック
     */
    @Stateless
    public class EditLogicImpl implements EditLogic {
    
        @Inject
        private DeptDao dao;
    
        /**
         * 初期処理
         * @param bean 編集画面のバッキングBean
         */
        @Override
        public void init(EditBean bean){
            Long id = bean.getId();
            if(id != null){
                Dept dept = dao.findById(id);
                bean.setId(dept.getId());
                bean.setDeptName(dept.getDeptName());
                bean.setDeptNo(dept.getDeptNo());
                bean.setLoc(dept.getLoc());
                bean.setVersionNo(dept.getVersionNo());
                bean.setDisableId(true);
                bean.setDisableDeptNo(true);
            }
            if(bean.getVersionNo() == null){
                bean.setVersionNo(0);
            }
        }
    
        /**
         * 保存処理
         * @param bean 編集画面のバッキングBean
         */
        @Override
        public void save(EditBean bean){
            Dept dept = new Dept();
            dept.setId(bean.getId());
            dept.setDeptName(bean.getDeptName());
            dept.setDeptNo(bean.getDeptNo());
            dept.setLoc(bean.getLoc());
            if(bean.getVersionNo() != null){
                dept.setVersionNo(bean.getVersionNo());
            }else{
                dept.setVersionNo(0);
            }
    
            if((dao.findDeptNo(bean.getDeptNo())) != null){
                FacesContext context = FacesContext.getCurrentInstance();
                context.addMessage("", CommonUtil.getFacesInfoMessage("messages.add.error.dept.duplicate"));
            }else{
                if(bean.isDisableId()){
                    // 更新
                    dao.update(dept);
                    bean.setVersionNo(dept.getVersionNo());
                }else{
                    // 新規登録
                    dao.insert(dept);
                    bean.setDisableId(true);
                    bean.setDisableDeptNo(true);
                }
            }
        }
    
        /**
         * 削除処理
         * @param bean 編集画面のバッキングBean
         */
        @Override
        public void delete(EditBean bean){
            // 削除
            dao.delete(bean.getId());
        }
    }
    
```

```

    /**
     * 部署テーブルのDAO
     *
     */
    @Stateless
    public class DeptDao extends AbstractDao {
    
        /**
         * 全部署を取得
         * @return
         */
        public List<Dept> findAll(){
            // 全件取得
            return em.createQuery(em.getCriteriaBuilder().createQuery(Dept.class)).getResultList();
        }
    
        /**
         * 部署取得
         * @param id 部署ID
         * @return 部署
         */
        public Dept findById(long id){
            return em.find(Dept.class, id);
        }
    
        /**
         * 部署一覧取得
         * @param id 部署ID
         * @param deptNo 部署番号
         * @param deptName 部署名
         * @param location 場所
         * @return
         */
        public List<Dept> find(Long id, Integer deptNo, String deptName, String location){
            // クエリの生成
            CriteriaBuilder cb = em.getCriteriaBuilder();
            CriteriaQuery<Dept> query = cb.createQuery(Dept.class);
            Root<Dept> r = query.from(Dept.class);
    
            // SELECTを生成
            query.select(r);
    
            // WHEREを生成
            List<Predicate> wheres = new ArrayList<>();
            if(id != null) wheres.add(cb.equal(r.get(Dept_.id), id));
            if(deptNo != null) wheres.add(cb.equal(r.get(Dept_.deptNo), deptNo));
            if(deptName != null && !deptName.equals("")) wheres.add(cb.like(r.get(Dept_.deptName), "%" + deptName + "%"));
            if(location != null && !location.equals("")) wheres.add(cb.like(r.get(Dept_.loc), "%" + location + "%"));
            query.where(wheres.toArray(new Predicate[]{}));
            query.orderBy(cb.asc(r.get(Dept_.deptNo)));
    
            // クエリを実行
            return em.createQuery(query).getResultList();
        }
    
        /**
         * 部署登録
         * @param dept 登録する部署
         * @return
         */
        public void insert(Dept dept){
            // insert
            em.persist(dept);
        }
    
        /**
         * 部署更新
         * @param dept 更新する部署
         */
        public void update(Dept dept){
            // versionNo更新
            dept.setVersionNo(dept.getVersionNo() + 1);
    
            // update
            em.merge(dept);
        }
    
        /**
         * 部署削除
         * @param id 削除する部署のID
         */
        public void delete(long id){
            // select & delete
            em.remove(findById(id));
        }
    
        /**
         * 検索したDEPT_NOと一致するDEPT_NOを取得
         */
        public Integer findDeptNo(Integer deptNo) {
            CriteriaBuilder cb = em.getCriteriaBuilder();
            CriteriaQuery<Integer> query = cb.createQuery(Integer.class);
            Root<Dept> r = query.from(Dept.class);
            //SELECT文でDEPT_NOを取得
            query.select(r.get(Dept_.deptNo));
            //WHERE文でDEPT_NOと一致する条件指定
            query.where(cb.equal(r.get(Dept_.deptNo), deptNo));
            return em.createQuery(query).getSingleResult();
        }
    }
    
    
```
CC BY-SA 4.0
2020-04-06T06:06:06.683
65390
2020-04-08T07:12:33.457
2020-04-08T02:33:08.500
question
java-ee
新規登録時にエラー画面に遷移してしまう
自己解決しました。

```

    /**
         * 検索したDEPT_NOと一致するDEPT_NOを取得
         */
        public Integer findDeptNo(Integer deptNo) {
            CriteriaBuilder cb = em.getCriteriaBuilder();
            CriteriaQuery<Integer> query = cb.createQuery(Integer.class);
            Root<Dept> r = query.from(Dept.class);
            //SELECT文でDEPT_NOを取得
            query.select(r.get(Dept_.deptNo));
            //WHERE文でDEPT_NOと一致する条件指定
            query.where(cb.equal(r.get(Dept_.deptNo), deptNo));
            return em.createQuery(query).getSingleResult();
        }
    
```

getSingleResultでNoResultExceptionの例外処理をしていなかったことが原因でした。有難うございました。
CC BY-SA 4.0
2020-04-08T07:12:33.457
65463
2020-04-08T07:12:33.457
65390
answer