画像データとテキストデータの関連付け。java H2データベースを使用してつぶやきアプリの制作をしています

実現したいこと

現在Twitter(X)のようなつぶやきアプリの制作をしています。
画像を格納するテーブルと、テキストを格納するテーブルの2つがあります。
画像とテキストデータを関連付けて表示させたいです。(関連付けて投稿したつもりでもテキストのみ、と画像のみという判定になってしまう)

発生している問題・分からないこと

ユーザー情報登録→それを使用してログイン→メイン画面(実際につぶやきをするタイムライン)
ログインまではできており、実際に送信をすることでテキストと画像データもデータベースへと格納までできています。コメントを送信するとタイムラインに新しいものから順に表示され、画像も同じように表示されます。しかし、どうしてもテキストと画像を関連付けて表示することができません。
テーブルにも参照整合性制約を持たせてもみましたが、制約違反が解決できず現在は制約をはずしました。画像は格納されても、テキストテーブルと同じIDを挿入できません。nullと表示されてしまいます。

なぜnullになってしまうのか、なぜ制約をもたせると違反になってしまうのか、その解決と、テキストと画像を効率的に関連付ける方法があれば教えていただきたいです。

先週の金曜日から今日まで50時間以上同じところで悩んでいます。できれば一人で解決したかったのですが、ここ二日は考えすぎて睡眠もとれず徹夜状態で頭がおかしくなりそうで相談させていただくことにしました。よろしくお願いします。
プログラミングをはじめて2か月にも満たない初心者で突っ込みどころの多いコードだと思います。
他にロジッククラスやBOクラスがありますがそちらは特に問題ではないと思っていますが、非常に多いので、問題のありそうだと思われるところを抜粋しますがもし足りない情報があれば追加します。
SELECTの部分もかなり不安があるので本当はのせたいのですが9000字という制限で全部はれないですごめんなさい。

該当のソースコード

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // リクエストパラメータの取得 request.setCharacterEncoding("UTF-8"); String text = request.getParameter("text"); request.setCharacterEncoding("UTF-8"); List<String> images = new ArrayList<String>(); // postされたパラメータの確認 String name = request.getParameter("name"); Part filePart = request.getPart("file1"); if (!text.isEmpty() && filePart != null && filePart.getSize() > 0) { // セッションスコープに保存されたユーザー情報を取得 HttpSession session = request.getSession(); User loginUser = (User) session.getAttribute("loginUser"); // つぶやきをつぶやきリストに追加 Mutter mutter = new Mutter(loginUser.getName(), text); PostMutterLogic postMutterLogic = new PostMutterLogic(); postMutterLogic.execute(mutter); // 画像のアップロード処理 String filename = makeUploadedFileName(filePart); InputStream fileContent = filePart.getInputStream(); String contentType = filePart.getContentType(); Image image = new Image(filename, fileContent, contentType); PostImageLogic postImageLogic = new PostImageLogic(); try { postImageLogic.execute(image); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } }else if (text == null || text.isEmpty()) { // 画像のアップロード処理 String filename = makeUploadedFileName(filePart); InputStream fileContent = filePart.getInputStream(); String contentType = filePart.getContentType(); Image image = new Image(filename,fileContent,contentType); PostImageLogic postImageLogic = new PostImageLogic(); try { postImageLogic.execute(image); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } } else if (!text.isEmpty()){ // セッションスコープに保存されたユーザー情報を取得 HttpSession session = request.getSession(); User loginUser = (User) session.getAttribute("loginUser"); // つぶやきをつぶやきリストに追加 Mutter mutter = new Mutter(loginUser.getName(), text); PostMutterLogic postMutterLogic = new PostMutterLogic(); postMutterLogic.execute(mutter); }
public class ImageDAO { // データベース接続に使用する情報 private final static String JDBC_URL = "jdbc:h2:tcp://localhost/~/dokoTsubuUp"; private final static String DB_USER = "sa"; private final static String DB_PASS = ""; //画像とテキストの両方を投稿した場合の処理 public boolean create(Image image) { try (Connection conn = DriverManager.getConnection(JDBC_URL, DB_USER, DB_PASS)) { String sql = "INSERT INTO FILEPATHS (content, content_type, uploaded_at) VALUES (?, ?, ?)"; try (PreparedStatement pstmt = conn.prepareStatement(sql)) { pstmt.setBlob(1, image.getFileContent()); pstmt.setString(2, image.getContentType()); pstmt.setTimestamp(3, Timestamp.valueOf(LocalDateTime.now())); int result = pstmt.executeUpdate(); return result == 1; } } catch (SQLException e) { e.printStackTrace(); return false; } } public boolean insertTextAndImage(Mutter mutter, Image image) { try (Connection conn = DriverManager.getConnection(JDBC_URL, DB_USER, DB_PASS)) { conn.setAutoCommit(false); // トランザクションを開始 // テキストを挿入 String insertMutterSQL = "INSERT INTO MUTTERS (name, text, tweet_date) VALUES (?, ?, ?)"; try (PreparedStatement pstmtMutter = conn.prepareStatement(insertMutterSQL, Statement.RETURN_GENERATED_KEYS)) { pstmtMutter.setString(1, mutter.getUserName()); pstmtMutter.setString(2, mutter.getText()); pstmtMutter.setDate(3, new java.sql.Date(System.currentTimeMillis())); int affectedRows = pstmtMutter.executeUpdate(); if (affectedRows == 0) { conn.rollback(); // ロールバック return false; } try (ResultSet generatedKeys = pstmtMutter.getGeneratedKeys()) { if (generatedKeys.next()) { int mutterId = generatedKeys.getInt(1); // 画像を挿入 String insertImageSQL = "INSERT INTO FILEPATHS (mutter_id, content, content_type) VALUES (?, ?, ?)"; try (PreparedStatement pstmtImage = conn.prepareStatement(insertImageSQL)) { pstmtImage.setInt(1, mutterId); pstmtImage.setBlob(2, image.getFileContent()); pstmtImage.setString(3, image.getContentType()); affectedRows = pstmtImage.executeUpdate(); if (affectedRows == 0) { conn.rollback(); // ロールバック return false; } } } } } conn.commit(); // コミット return true; } catch (SQLException e) { e.printStackTrace(); return false; } } }
public int create(Mutter mutter) { int mutterId = -1; // 初期値として無効なIDを設定 // JDBCドライバを読み込む try { Class.forName("org.h2.Driver"); } catch (ClassNotFoundException e) { throw new IllegalStateException("JDBCドライバを読み込めませんでした"); } // データベース接続 try (Connection conn = DriverManager.getConnection(JDBC_URL, DB_USER, DB_PASS)) { // INSERT文の準備 String sql = "INSERT INTO MUTTERS(name, text, tweet_date) VALUES (?, ?, ?)"; PreparedStatement pStmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS); // INSERT文中の「?」に使用する値を設定しSQLを完成 pStmt.setString(1, mutter.getUserName()); pStmt.setString(2, mutter.getText()); pStmt.setDate(3, new java.sql.Date(System.currentTimeMillis())); // タイムスタンプの取得と設定 // INSERT文を実行し、自動生成されたIDを取得する int result = pStmt.executeUpdate(); if (result == 1) { ResultSet generatedKeys = pStmt.getGeneratedKeys(); if (generatedKeys.next()) { mutterId = generatedKeys.getInt(1); // 自動生成されたIDを取得 } else { throw new SQLException("Failed to get generated keys."); } } } catch (SQLException e) { e.printStackTrace(); } return mutterId; // 挿入されたテキストのIDを返す } }

試したこと・調べたこと

上記の詳細・結果

特に改善はみられず、むしろ最初のころより冗長になってる気もします…
他にはAIを使用してエラーチェックなど行っています。

補足

Tomcat9_java17
Eclipse使用

コメントを投稿

0 コメント