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

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

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

Oracleは、米オラクルが取り扱うリレーショナルデータベース管理システムです。メインフレームからPCまで、多様なプラットフォームに対応しています。

PostgreSQL

PostgreSQLはオープンソースのオブジェクトリレーショナルデータベース管理システムです。 Oracle Databaseで使われるPL/SQLを参考に実装されたビルトイン言語で、Windows、 Mac、Linux、UNIX、MSなどいくつものプラットフォームに対応しています。

Java

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

Spring

Spring Framework は、Javaプラットフォーム向けのオープンソースアプリケーションフレームワークです。 Java Platform上に、 Web ベースのアプリケーションを設計するための拡張機能が数多く用意されています。

検索

検索は、あるデータの集まりの中から 目的のデータを見つけ出すことです。

Q&A

解決済

2回答

3159閲覧

Spring Data JPA を使用した検索を行うと、検索結果が0件になる件について

fnXJ3jPE1tDXd7N

総合スコア10

Oracle

Oracleは、米オラクルが取り扱うリレーショナルデータベース管理システムです。メインフレームからPCまで、多様なプラットフォームに対応しています。

PostgreSQL

PostgreSQLはオープンソースのオブジェクトリレーショナルデータベース管理システムです。 Oracle Databaseで使われるPL/SQLを参考に実装されたビルトイン言語で、Windows、 Mac、Linux、UNIX、MSなどいくつものプラットフォームに対応しています。

Java

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

Spring

Spring Framework は、Javaプラットフォーム向けのオープンソースアプリケーションフレームワークです。 Java Platform上に、 Web ベースのアプリケーションを設計するための拡張機能が数多く用意されています。

検索

検索は、あるデータの集まりの中から 目的のデータを見つけ出すことです。

0グッド

0クリップ

投稿2022/01/07 05:54

編集2022/01/16 09:06

Spring Data JPA のクエリメソッド名を使用した検索を行うと、検索結果が0件になる

チュートリアルを基に、Springを学習中です。
チュートリアルではPostgreSQLを使用していましたが、手持ちの環境の都合上、Oracle 18c XEを使用しました。
「メソッド名からクエリを生成する方法」の所で、意図した検索結果にならず、つまづいています。
具体的には、生成されたクエリを実行すると、SQL Plusだと検索されますが、プログラムからは検索結果が0件になってしまいます。

発生している問題・エラーメッセージ

ログから、以下のクエリが生成されていることを確認しました。
バインドされた値も確認しました。

log

12022-01-07 10:50:52.422 DEBUG 16596 --- [nio-8080-exec-1] org.hibernate.SQL : 2 select 3 reservable0_.reserved_date as reserved_date1_1_, 4 reservable0_.room_id as room_id2_1_ 5 from 6 reservable_room reservable0_ 7 where 8 reservable0_.reserved_date=? 9 order by 10 reservable0_.room_id asc 11Hibernate: 12 select 13 reservable0_.reserved_date as reserved_date1_1_, 14 reservable0_.room_id as room_id2_1_ 15 from 16 reservable_room reservable0_ 17 where 18 reservable0_.reserved_date=? 19 order by 20 reservable0_.room_id asc 212022-01-07 10:50:52.423 TRACE 16596 --- [nio-8080-exec-1] o.h.type.descriptor.sql.BasicBinder : binding parameter [1] as [VARCHAR] - [2022-01-07]

SQL Plusの実行結果は以下の通りです(一部省略)。

sql

1SQL> select 2 2 reservable0_.reserved_date as reserved_date1_1_, 3 3 reservable0_.room_id as room_id2_1_ 4 4 from 5 5 reservable_room reservable0_ 6 6 where 7 7 reservable0_.reserved_date='2022-01-07' 8 8 order by 9 9 reservable0_.room_id asc; 10 11RESERVED_DATE1_1_ 12-------------------- 13ROOM_ID2_1_ 14----------- 152022-01-07 16 1 17 182022-01-07 19 2 20 212022-01-07 22 3 23(以降省略) 24 257行が選択されました。

これが、プログラムの実行結果を確認すると、検索結果が0件になります。

該当のソースコード

検索の実行個所は以下の通りです(一部抜粋)。

java

1 @RequestMapping(method = RequestMethod.GET) 2 String listRooms(Model model) { 3 String date = LocalDate.now().toString(); 4 5 List<ReservableRoom> rooms = roomService.findReservableRooms(date); 6 // デバッグ用 7 System.out.println("rooms count:" + rooms.size()); //ここが0件になる 8 9 model.addAttribute("date", date); 10 model.addAttribute("rooms", rooms); 11 return "room/listRooms"; 12 }

検索メソッドのソースは以下の通りです(エンティティのゲッター/セッターは省略しています)。

java

1@Service 2@Transactional 3public class RoomService { 4 5 @Autowired 6 ReservableRoomRepository reservableRoomRepository; 7 8 public List<ReservableRoom> findReservableRooms(String date) { 9 return reservableRoomRepository.findByReservableRoomId_reservedDateOrderByReservableRoomId_roomIdAsc(date); 10 } 11}

java

1public interface ReservableRoomRepository extends JpaRepository<ReservableRoom, ReservableRoomId> { 2 List<ReservableRoom> findByReservableRoomId_reservedDateOrderByReservableRoomId_roomIdAsc(String reservedDate); 3}

java

1@Entity 2public class ReservableRoom implements Serializable { 3 @EmbeddedId 4 private ReservableRoomId reservableRoomId; 5 6 @ManyToOne 7 @JoinColumn(name = "room_id", insertable = false, updatable = false) 8 @MapsId("roomId") 9 private MeetingRoom meetingRoom; 10 11 public ReservableRoom(ReservableRoomId reservableRoomId) { 12 this.reservableRoomId = reservableRoomId; 13 } 14 15 public ReservableRoom() { 16 } 17 //getter/setterは省略 18}

java

1@Embeddable 2public class ReservableRoomId implements Serializable { 3 private Integer roomId; 4 private String reservedDate; 5 6 public ReservableRoomId(Integer roomId, String reservedDate) { 7 this.roomId = roomId; 8 this.reservedDate = reservedDate; 9 } 10 11 public ReservableRoomId() { 12 } 13 14 @Override 15 public int hashCode() { 16 final int prime = 31; 17 int result = 1; 18 result = prime * result + ((reservedDate == null) ? 0 : reservedDate.hashCode()); 19 result = prime * result + ((roomId == null) ? 0 : roomId.hashCode()); 20 return result; 21 } 22 23 @Override 24 public boolean equals(Object obj) { 25 if(this == obj) return true; 26 if(obj == null) return false; 27 if(getClass() != obj.getClass()) return false; 28 ReservableRoomId other = (ReservableRoomId) obj; 29 if(reservedDate == null) { 30 if(other.reservedDate != null) return false; 31 }else if(!reservedDate.equals(other.reservedDate)) 32 return false; 33 if(roomId == null) { 34 if(other.roomId != null) return false; 35 }else if(!roomId.equals(other.roomId)) 36 return false; 37 return true; 38 } 39 //getter/setterは省略 40}

試したこと

  • ログの確認
  • SQL Plusでの動作検証
  • デバッグ出力の追加
  • PostgreSQLとOracleの非互換調査
  • チュートリアルとのソースの突合せ
  • Spring Data JPA リファレンスの確認
  • Googleで類似事例の確認

補足情報(FW/ツールのバージョンなど)

  • Spring Boot 2.6.2
  • Java 11
  • Oracle 18c XE

2022/01/10追記

「SQL Plusとプログラムで、見ているデータベースが異なるのではないか」とのご指摘をいただきました。
同じデータベースを参照している認識です。
以下に、SQL Plusのログインとapplication.propertiesを掲載します。

sql

1connect xxxx/xxxx@//localhost:1521/XEPDB1

properties

1spring.datasource.driver-class-name=oracle.jdbc.driver.OracleDriver 2spring.datasource.url=jdbc:oracle:thin:@//localhost:1521/XEPDB1 3spring.datasource.username=xxxx 4spring.datasource.password=xxxx 5spring.jpa.database-platform=org.hibernate.dialect.Oracle10gDialect 6spring.jpa.show-sql=true 7spring.jpa.hibernate.ddl-auto=validate 8spring.jpa.properties.hibernate.format_sql=true 9spring.sql.init.encoding=UTF-8 10logging.level.org.hibernate.SQL=DEBUG 11logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE

2022/01/13追記

application.propertiesに以下を追記し、schema.sqlとdata.sqlからデータベースを作成してみたところ、正常に動作しました。

properties

1spring.sql.init.mode=always 2spring.sql.init.schema-locations=classpath:schema.sql

「SQL Plusとプログラムで、見ているデータベースが異なるのではないか」とのご指摘の通りのようですが、理屈があまり理解できていません。
SQL Plusのconnectの書式か、spring.datasource.urlの書式のどちらかが誤っているのでしょうか?

2022/01/16追記

SQL PlusでテーブルをDROPして、アプリ側で「テーブル無し」のエラーとなることを確認しました。
SQL Plusでテーブルを作成する際に、わざとカラム属性を誤った属性にしたところ、エンティティの生成でエラーとなることを確認しました。
以上のことから、SQL Plusとプログラムで見ているデータベースは同じであると考えられます。
しかし、レコードのINSERTだけ、SQL Plusとプログラムで振る舞いが異なることを確認しています。

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

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

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

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

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

shiketa

2022/01/10 01:47

> 具体的には、生成されたクエリを実行すると、SQL Plusだと検索されますが、プログラムからは検索結果が0件になってしまいます。 ほんとうに、双方で同じデータベースを参照しているのでしょうか。それぞれ別のデータベースを参照して、ないない騒ぐ景色には、まま遭遇します。
Orlofsky

2022/01/11 09:38

同じSQLでもデータベースやバージョンの違いによる方言は大きいです。無用なトラブルを避けるためにも、開発環境に本番環境と同じデータベースやバージョンを用意するのは基本中の基本です。
fnXJ3jPE1tDXd7N

2022/01/11 10:24

>無用なトラブルを避けるためにも、開発環境に本番環境と同じデータベースやバージョンを用意するのは基本中の基本です。 本当の開発現場であれば、おっしゃる通りですね。 今回は自学自習であることと、担当している現場がOracleだったので、Oracleでチャレンジしてみました。 一応PostgreSQLでも動作確認を行い、チュートリアル通りの動作になることは確認しています。
guest

回答2

0

自己解決

解決しました。

修正前:

java

1 String date = LocalDate.now().toString();

修正後:

java

1 DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); 2 String date = LocalDate.now().format(dateTimeFormatter);

投稿2022/01/16 09:41

編集2022/01/16 09:43
fnXJ3jPE1tDXd7N

総合スコア10

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

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

0

java

1String date = LocalDate.now().toString();

ざっと見る限り、この部分が悪さをしていそうですね。Spring JPAはLocalDateもサポートしていたはずなので、以下のようにしてみてはどうでしょうか?

java

1public interface ReservableRoomRepository extends JpaRepository<ReservableRoom, ReservableRoomId> { 2 List<ReservableRoom> findByReservableRoomId_reservedDateOrderByReservableRoomId_roomIdAsc(LocalDate reservedDate); 3}

投稿2022/01/15 06:39

neko_the_shadow

総合スコア2349

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問