hibernate/hql を使用してクエリを作成しています。ここで状況を理解するために、私はかなりの時間立ち往生している問題を抱えています。
情報を取得する必要がある 3 つのテーブルを取得し、全体で 5 つの接続/割り当てテーブルを取得しました。必要な情報は Key、Type、および SourceFile ですが、ここでの特別なケースは、新しいデータのインポート中に SQL が実行されることです。そのため、データが既に存在するか、部分的に存在するかを最初に確認したいと考えています。キー自体が既にデータベースにある場合、Type または SourceFile に関係なく、クエリは常にキーを提供する必要があります。また、キーのみが必要であり、他の情報は必要ありません。(キーは一致しますが、SourceFile と Type は一致しないので、キーだけを返したいです) Key がまったく同じ Type と SourceFile で存在する場合、すべての情報を取得したいと考えています。
テーブルは次のとおりです。
(注意: FK_K_ID は名前キーを持つオブジェクトとして保存され、FK_S_ID はソースとして保存され、FK_T_ID はタイプとして保存されます)
鍵:
+-------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+--------------+------+-----+---------+----------------+
| K_ID | bigint(20) | NO | PRI | NULL | auto_increment |
| key | varchar(255) | NO | | NULL | |
| deleted | boolean | NO | | FALSE | |
+-------------+--------------+------+-----+---------+----------------+
キータイプ:
+-------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+--------------+------+-----+---------+----------------+
| KT_ID | bigint(20) | NO | PRI | NULL | auto_increment |
| FK_K_ID | bigint(20) | NO | | NULL | |
| FK_T_ID | bigint(20) | NO | | NULL | |
| deleted | boolean | NO | | FALSE | |
+-------------+--------------+------+-----+---------+----------------+
タイプ:
+-------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+--------------+------+-----+---------+----------------+
| T_ID | bigint(20) | NO | PRI | NULL | auto_increment |
| name | varchar(255) | NO | | NULL | |
| description | varchar(255) | NO | | NULL | |
| deleted | boolean | NO | | FALSE | |
+-------------+--------------+------+-----+---------+----------------+
キーソース:
+-------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+--------------+------+-----+---------+----------------+
| KS_ID | bigint(20) | NO | PRI | NULL | auto_increment |
| FK_K_ID | bigint(20) | NO | | NULL | |
| FK_S_ID | bigint(20) | NO | | NULL | |
| deleted | boolean | NO | | FALSE | |
+-------------+--------------+------+-----+---------+----------------+
ソース:
+-------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+--------------+------+-----+---------+----------------+
| S_ID | bigint(20) | NO | PRI | NULL | auto_increment |
| sourceFile | varchar(255) | NO | | NULL | |
| deleted | boolean | NO | | FALSE | |
+-------------+--------------+------+-----+---------+----------------+
これが私がこれまでに試したことです:
from KeyType kt
right outer join kt.Key k
with k.name in (...)
where k.deleted = false
and ( kt.Type in (...) or kt is null )
これの問題は、それが私が望むことをするということです。しかし、データベース内のすべてのキーと、一致する場所のみの KeyType を取得し、それ以外の場合は null を取得します。すべてのキーを取得するのではなく、要求したキーを取得したいだけです。
from KeyType kt
right outer join kt.Key k
with k.name in (...)
where k.deleted = false
and (k.name in (...) and kt.Type in (...) or kt is null )
正直に言うと、ここで何を試みたのかさえわかりません。最初のクエリを最適化して、要求したキーのみを提供しようとしたと思います。
from KeyType kt
right outer join fetch kt.Key k
where k.deleted = false
and (k.name in (...) and kt.Type in (...) or kt is null )
また、このようなまたは他のバリエーションでフェッチを使用しようとしましたが、必要なように機能しませんでした。
from Key k
left outer join KeyType kt on kt.Key.id = k.id
left outer join KeySource ks on ks.Key.id = k.id
inner join Source s on ks.Source.id = s.id
where k.deleted = false
and k.name in (...)
and ( kt.appType in (...) or kt is null )
and ( s.SourceFile in (...) or s is null )
予想通り、これは機能しません。つまり、うまくいかないことがわかるのは非常に簡単ですが、うまくいかない場合はたくさん試してみてください。
さらに多くのクエリの組み合わせとバリエーションを試しましたが、うまくいきませんでした。最初のクエリは、私が得た最も近いものです。誰かが私を助けてくれることを願っています。
PS: 今はマッピングやエンティティを変更できません。私は得たもので働かなければなりません。
アップデート:
わかりましたので、問題の解決に非常に近づいています。私のクエリは次のようになります。
select k, case when kt.Type not in (...) then null
else 1 end
from KeyType kt
join kt.Key k
where k.name in (...)
今私がしたいのは、1を実際のオブジェクトと交換することだけです。しかし、これを行うと、「org.hibernate.exception.GenericJDBCException: could not execute query」というエラーが表示されます (Oracle データベースで実行)
誰かがそれを解決する方法を教えてもらえますか?