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

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

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

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

Java

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

Q&A

解決済

3回答

8130閲覧

(JPA)(Oracle) OracleのNUMBER型にupdate文でnullを格納できない。

_cocapeach

総合スコア20

Oracle

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

Java

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

0グッド

0クリップ

投稿2018/09/26 10:05

編集2018/09/27 02:48

お世話になります。
OracleでNumber型として保持しているカラムをJavaでLong型として定義しています。
そのカラムにUpdate文でNULLを入れると、

ORA-00932: データ型が一致しません: NUMBERが予想されましたがBINARYです。

というエラーが発生してしまいます。
調べたのですが、自分と同じような現象の記事がなく、解決に至りませんでした。
ご教示頂けますと幸いです。

//Table "COLUMN_NAME","DATA_TYPE","NULLABLE","DATA_DEFAULT","COLUMN_ID","COMMENTS" "Hoge","NUMBER(2,0)","Yes","",18,""
//Entity @Entity @Table(name = "hogehoge") public class Hogehoge { @ManyToOne @JoinColumn(name = "Hoge") private Hoge hoge; }
//Repository @Modifying @Query("UPDATE Hogehoge SET Hoge = :Hoge") Integer updateByHoge(@Param("Hoge") Long Hoge);
//Controller //form.getHogeはLong型 NULLを返す場合がある HogehogeRepository.updateByHoge(form.getHoge());
//ログ 2018-09-27 11:05:23.946 DEBUG 92809 --- [nio-8080-exec-7] org.hibernate.SQL : update Hogehoge set Hoge=? where id=? //↓値が入った場合はBIGINT型でパラメータがセットされているが、NULLの場合はVARBINARY型でセットされている。 2018-09-27 11:05:23.955 TRACE 92809 --- [nio-8080-exec-7] o.h.type.descriptor.sql.BasicBinder : binding parameter [1] as [VARBINARY] - [null] 2018-09-27 11:05:23.955 TRACE 92809 --- [nio-8080-exec-7] o.h.type.descriptor.sql.BasicBinder : binding parameter [2] as [BIGINT] - [1] 2018-09-27 11:05:24.322 WARN 92809 --- [nio-8080-exec-7] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 932, SQLState: 42000 2018-09-27 11:05:24.322 ERROR 92809 --- [nio-8080-exec-7] o.h.engine.jdbc.spi.SqlExceptionHelper : ORA-00932: データ型が一致しません: NUMBERが予想されましたがBINARYです。

・試してみたこと①

@Modifying @Query("UPDATE Hogehoge SET Hoge = :Hoge") Integer updateByHoge(@Param("Hoge") Long Hoge); ↓ @Modifying @Query("UPDATE Hogehoge SET Hoge = CASE WHEN :Hoge != null THEN :Hoge ELSE null END") Integer updateByHoge(@Param("Hoge") Long Hoge); //これは成功しましたが、全てのUpdate文に適用させるとなると非常に膨大な作業になってしまうため、他の解決策を探しています。

・試してみたこと②

//Repository //引数の型をStringに変更 @Modifying @Query("UPDATE Hogehoge SET Hoge = :Hoge") Integer updateByHoge(@Param("Hoge") String Hoge); //Controller HogehogeRepository.updateByHoge(form.getHoge()!=null?form.getHoge.toString():null); //StringだとNullが通りましたが、こちらも作業量が膨大なため、他の解決策を探しています。

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

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

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

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

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

guest

回答3

0

自己解決

//Entity @Entity @Table(name = "hogehoge") public class Hogehoge { @ManyToOne @JoinColumn(name = "Hoge") private Hoge hoge; //上記のような定義をしていると、Hogeの値がNULLであった場合、 //DBではNUMBER型で値を保持していても数値型でNULLをセットしてくれないらしいです。 //下記のようにHogeのidを別変数で定義してあげると解決致しました。 @ManyToOne @JoinColumn(name = "Hoge", insertable = false, updatable = false) private Hoge hoge; @Column(name = "Hoge") private Long hogeid; }

投稿2018/09/27 02:54

_cocapeach

総合スコア20

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

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

0

試せる環境を持っていないので、直接の回答にはならないのですが、
JPAのQuery(JPQL)は実行時にフレームワークのほうでSQLに変換されて実行されます。
その際、どのようなSQLに変換されたかログに出すことができますので、ログで変換後SQLを調べてみたら解決策が見いだせるかもしれません。
(0x00000000 みたいな値がSETされていると予想します)

ログの出力方法は、"jpa query sql ログ" で検索するといろいろな方法が出てくるので環境にあった方法をセットしてみてください。
persistence.xmlに記載する方法が一番シンプルでしょうか。

どうしてもダメならNativeQueryという生のSQLを書く方法もありますが、JPAのメリットはミナゴロシになるので最終手段です。

投稿2018/09/26 22:31

hope_mucci

総合スコア4447

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

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

_cocapeach

2018/09/27 00:11

hope_mucci様 有難うございます。 今もログ出力は行なっているのですが、値の部分が?と出力されています。 他の方法でログ出力を行なってみます。 ということは、NULLがNULLとして変換されていない もしくはNULLがOracle側でNULLとして認識できていないということでしょうか?
_cocapeach

2018/09/27 02:32 編集

見る箇所を間違えていました。Javaでは、Integer型ではなく、Long型で定義しておりました。 また、ログを見たところ、値が入っている時はBIGINT型でパラメータがセットされているのですが、値が入っていない時はVARBINARY型としてNULLがセットされていました。ここが原因だと思うのですが、なぜVARBINARYになってしまうのかわかりません。
guest

0

Java の部分はわかりません。

テーブル定義はCREATE TABLE文で載せてください。

UPDATE Hogehoge SET Hoge = CASE WHEN :Hoge != null THEN :Hoge ELSE null END

SQLでは NULL かは、

COL1 IS NULL

NULL でないかは

COL1 IS NOT NULL

と記述します。

津島博士のパフォーマンス講座 第9回 良いSQLについて - 索引を使用しない は熟読しておいてください。

投稿2018/09/26 14:44

Orlofsky

総合スコア16415

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

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

_cocapeach

2018/09/26 22:06

Orlfsky様 有難うございます。 SQLにてNULLを入れる事は出来ているのですが、Integer型の引数からNULLを渡すとエラーになってしまうのです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問