質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Q&A

解決済

1回答

4179閲覧

DBエラーにおいて接続失敗と未存在エラーを分けたい

Linkey

総合スコア77

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

0グッド

0クリップ

投稿2017/07/16 04:46

編集2017/07/16 23:14

JavaのJPAを使用してWebアプリケーションを作成しています。
今、実装している仮会員テーブルの検索でDB検索結果が0件の場合に「ただのDbエラーではなくレコード未存在のエラー」としてはっきりさせたいと考えています。
しかし、調べて見たところそのような独特?の実装している参考のソースコードが見つからず質問を投稿しました。DBエラーのcatch内部でレコード未存在なのかテーブル未存在なのかを判定することは可能でしょうか?

ビジネスロジッククラス

Java

1package registration.business_logic; 2 3import java.util.ArrayList; 4import java.util.Random; 5 6import registration.dao.PreUserDAO; 7import registration.entity.PreUserEntity; 8import util.exception.RestaurantDaoException; 9 10public class RegistrationBusinessLogic { 11 PreUserDAO dao = null; 12 public void gettingPreUserIdFromDatabase() { 13 try { 14 PreUserEntity getPreUserIdList = null; 15 boolean duplicateFlag = true; 16 int duplicateCount = 0; 17 ArrayList<String> getPreUserList = new ArrayList<>(); 18 19 //まず仮会員IDを発番する 20 String id = null; 21 //TODO Logger.debug("ビジネスロジック処理開始", "処理={}", "generateIssuePreId"); 22 dao = new PreUserDAO(); 23 getPreUserIdList = dao.findAllPreUserId(); 24 while(duplicateFlag){ 25 if(duplicateCount >= 3){ 26 //TODO Logger.warn("仮会員ID発行失敗"); 27 //throw new RestaurantDaoException(); 28 System.out.println("仮会員ID発行失敗"); 29 break; 30 } 31 id = generateUserId(); 32 if (!getPreUserList.contains(id)) { 33 break; 34 } 35 //TODO Logger.debug("ID重複", "retryCount={}", i) 36 id = null; 37 duplicateCount++; 38 } 39 } catch (RestaurantDaoException e){ //独自例外として宣言したい 40 //TODO ログ出力 41 //Logger.error("DB検索失敗") 42 e.printStackTrace(); 43 } finally { 44 //TODO Logger.debug("ビジネスロジック処理終了", "処理={}", "generateIssuePreId"); 45 dao.close(); 46 } 47 } 48 49 // 8桁の仮ユーザIDを発行する 50 private String generateUserId() { 51 //TODO Logger.debug("仮会員ID発行処理開始") 52 Random rd = new Random(); 53 StringBuilder sb = new StringBuilder(); 54 int getNumber = 0; 55 int alphabetNumber = 0; 56 char getAlphabetCharacter = '\u0000'; 57 58 //カウント数をプロパティから取得する(今後ID不足で桁数が増えても大丈夫なように) 59 60 for (int loopCount = 0; loopCount < 8; loopCount++) { 61 int getParseNumber = rd.nextInt(4); // 0〜3の乱数を取得する 62 switch (getParseNumber) { 63 case 0:// 大文字を取得 64 alphabetNumber = 65; 65 getNumber = rd.nextInt(26); 66 alphabetNumber = alphabetNumber + getNumber; 67 getAlphabetCharacter = (char) alphabetNumber; 68 sb.append(String.valueOf(getAlphabetCharacter)); 69 break; 70 case 1:// 小文字を取得 71 alphabetNumber = 97; 72 getNumber = rd.nextInt(26); 73 alphabetNumber = alphabetNumber + getNumber; 74 getAlphabetCharacter = (char) alphabetNumber; 75 sb.append(String.valueOf(getAlphabetCharacter)); 76 break; 77 case 2:// 数値を取得 78 getNumber = rd.nextInt(10); 79 sb.append(String.valueOf(getNumber)); 80 break; 81 case 3:// 大文字を取得 82 alphabetNumber = 65; 83 getNumber = rd.nextInt(26); 84 alphabetNumber = alphabetNumber + getNumber; 85 getAlphabetCharacter = (char) alphabetNumber; 86 sb.append(String.valueOf(getAlphabetCharacter)); 87 break; 88 case 4:// 小文字を取得 89 alphabetNumber = 97; 90 getNumber = rd.nextInt(26); 91 alphabetNumber = alphabetNumber + getNumber; 92 getAlphabetCharacter = (char) alphabetNumber; 93 sb.append(String.valueOf(getAlphabetCharacter)); 94 break; 95 case 5:// 数値を取得 96 getNumber = rd.nextInt(10); 97 sb.append(String.valueOf(getNumber)); 98 break; 99 } 100 } 101 //TODO Logger.debug("仮会員ID発行処理終了") 102 return sb.toString(); 103 } 104}

Daoクラス

Java

1package registration.dao; 2 3import java.io.Closeable; 4 5import javax.persistence.EntityManager; 6import javax.persistence.EntityTransaction; 7import javax.persistence.TypedQuery; 8 9import registration.entity.PreUserEntity; 10import util.dao.EmProvider; 11import util.dao.ResourceDAO; 12import util.exception.RestaurantDaoException; 13 14/** 15 * 仮ユーザーテーブルにアクセスする 16 * 17 * @author user 18 * 19 */ 20public class PreUserDAO implements Closeable, ResourceDAO { 21 22 private final static String SQL_FIND_ALL_PRE_USER_ID = "PreUser.findAllPreCostomerId"; 23 private EntityManager em = null; 24 EntityTransaction et = null; 25 26 /** 27 * 仮会員IDを取得します 28 * @return entiy 29 * 検索結果 30 * DB検索とDB接続失敗のみを確認する 31 */ 32 public PreUserEntity findAllPreUserId() throws RestaurantDaoException { 33 34 EntityManager em = null; 35 try { 36 // Logger.debug("仮会員テーブル検索開始") 37 System.out.println("仮会員テーブル検索開始"); 38 em = EmProvider.getInstance().getEntityManagerFactory().createEntityManager(); 39 TypedQuery<PreUserEntity> query = em.createNamedQuery(SQL_FIND_ALL_PRE_USER_ID, PreUserEntity.class); 40 PreUserEntity entity = query.getSingleResult(); 41 42 // Logger.debug("仮会員テーブル検索終了") 43 return entity; 44 } catch (Exception e) { 45 throw new RestaurantDaoException("エラー内容を設定する" ,e); 46 //TODO 47 //ここでレコード未存在なのかテーブル未存在、そもそもアクセスエラー 48 //なのか失敗したのかを判定したい 49 50 } finally { 51 if (em != null) { 52 em.close(); 53 } 54 EmProvider.getInstance().closeEmf(); 55 } 56 } 57 58 @Override 59 public void close() { 60 if (em != null) { 61 em.close(); 62 } 63 } 64}

独自例外クラス

Java

1package util.exception; 2 3/* 4 * DBエラーを扱う例外クラス 5 */ 6public class RestaurantDaoException extends Exception { 7 8 public RestaurantDaoException(String errorMessage, Exception e) { 9 super(errorMessage , e); 10 } 11}

もう一つ実現させたいこと
エラーが発生すると以下のような背景にWarningのマークがあるエラーページにジャンプしてthrow newした時のエラー内容を表示する。
※エラーページイメージ
![イメージ説明

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

getSingleResult()は取得するデータが存在しない場合に、NoResultExceptionという例外が発生しますので、Exceptionの前にcatchすれば判別できると思います。

実装例

java

1try { 2 ・・・ 3 Use user = userService.getSingleResult(); 4 return user; 5 6} catch(NoResultException e){ 7 // データなしエラー処理 8 9 10} catch(Exception e){ 11 // その他例外処理 12}

例外情報の表示ですが、スタックトレース情報を全て出力する想定でしょうか?

投稿2017/07/18 05:13

mr-hisa-child

総合スコア294

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Linkey

2017/08/05 07:43

返信が遅れてしまい申し訳ありませんでした。例外情報はLogger.warnでログに出力する予定です。また今後は利用するテーブルが増えるため。1件だけ取得する検索とリストを作成するために複数の検索結果を取得するメソッドが必要になってきます。getSingleResultとgetResultList()でそれぞれ検索失敗か接続失敗を判定する方法を考えなければいけないと思いました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問