8

無効な SQL を生成する Hibernate に問題があります。具体的には、暗黙的結合と明示的結合の混合と一致。これは未解決のバグのようです。

ただし、これが無効な SQL である理由がわかりません。同じ構文例外を生成する小さなおもちゃの例を考え出しました。

スキーマ

CREATE TABLE Employee (
    employeeID INT,
    name VARCHAR(255),
    managerEmployeeID INT   
)

データ

INSERT INTO Employee (employeeID, name) VALUES (1, 'Gary')
INSERT INTO Employee (employeeID, name, managerEmployeeID) VALUES (2, 'Bob', 1)

ワーキングSQL

これらのクエリは両方とも機能します。デカルト積があることに気付きました。それは意図的なものです。

明示的な結合:

SELECT e1.name,
       e2.name,
       e1Manager.name
  FROM Employee e1
 CROSS JOIN Employee e2
 INNER JOIN Employee e1Manager
    ON e1.managerEmployeeID = e1Manager.employeeID

暗黙の結合:

SELECT e1.name,
       e2.name,
       e1Manager.name
  FROM Employee e1,
       Employee e2,
       Employee e1Manager
 WHERE e1.managerEmployeeID = e1Manager.employeeID

無効な SQL

このクエリは、MSSQL 2000/2008 または MySQL では機能しません。

SELECT e1.name, 
       e2.name, 
       e1Manager.name
  FROM Employee e1,
       Employee e2
 INNER JOIN Employee e1Manager 
    ON e1.managerEmployeeID = e1Manager.employeeID

MS2000 では、次のエラーが表示されます。

列のプレフィックス 'e1' が、クエリで使用されているテーブル名またはエイリアス名と一致しません。

MySQL では、エラーは次のとおりです。

「on 句」の不明な列「e1.managerEmployeeID」。

質問

  1. この構文が無効なのはなぜですか?
  2. おまけ: Hibernate に明示的な JOIN のみを使用させる方法はありますか?

4

3 に答える 3

15

JOINSQL 標準によれば、キーワードはコンマよりも優先順位が高いため、エラーになります。厄介な点は、対応するテーブルが句 で評価されるまで、テーブルのエイリアスを使用できないことです。FROM

したがって、式で参照e1すると、まだ存在しません。JOIN...ONe1

私が Hibernate を調査しJOIN、すべての場合に使用するよう説得できるかどうかを確認する間、しばらくお待ちください。


うーん。Hibernate.org のすべてが jboss.org にリダイレクトされているようです。そのため、現在 HQL のドキュメントをオンラインで読む方法はありません。彼らは最終的に彼らの名前が役立つと確信しています。

于 2009-04-17T18:18:31.443 に答える
1

ハイバネートにはまったく関係ないので、これは少し話題から外れているかもしれませんが、Bill Karwinからのコメントは本当に私の目を開かせてくれました。最初に暗黙的な結合を記述する代わりに、最初に明示的な結合を行う必要があります。この構文は、暗黙的な結合が複数ある場合に特に役立ちます。

MS SQL で次の例を確認してください。すべての連絡先に国コードが定義されているわけではありませんが、すべての連絡先にはテーブル Tbl で検索される属性 val があります。したがって、直感的なソリューションは機能しません。

SELECT * FROM 
contacts, Tbl
LEFT OUTER JOIN country ON CtryCod = country.CtryCod 
WHERE val = Tbl.val

代わりに、次の構文を使用することをお勧めします。

SELECT * FROM 
contacts LEFT OUTER JOIN country ON CtryCod = country.CtryCod, 
Tbl
WHERE val = Tbl.val
于 2013-03-22T13:01:30.083 に答える
0

PostgreSQL でもエラーが発生します。

ERROR:  invalid reference to FROM-clause entry for table "e1"
LINE 7:     ON e1.managerEmployeeID = e1Manager.employeeID;
               ^
HINT:  There is an entry for table "e1", but it cannot be referenced from this part of the query.

問題は、2 つのテーブル a と b (この場合は e2 と e1Manager) を結合すると、「ON」句でこれら 2 つのテーブルしか参照できないことだと思います。したがって、この ON 句では e2 と e1Manager を参照できますが、e1 は参照できません。

これは、「JOIN」ステートメントのチェーンがある場合、「ON」句で同じチェーン内の他のテーブルを参照できるように拡張されていると思いますが、「、」を越えることはできません。したがって、「a JOIN b ON a.a_id = b.a_id JOIN c ON c.b_id = b.b_id AND c.a_id = a.a_id」のようなものは許可されます。

この SQL を生成するために使用している HQL は何ですか? 「従業員e1、従業員e2からe1.name、e2.name、e1.manager.nameを選択」のようなものですか?

于 2009-04-17T18:19:31.643 に答える