Hibernateでのクエリに問題があるようです。 2つのテーブルで内部結合を実行しています。
SELECT * FROM product p INNER JOIN warehouse w ON p.wid = w.id
製品表:
id | name | wid | price | stock .....
倉庫テーブル:
id | name | city | lat | long .....
結合結果:
id | name | wid | price | stock | id | name | city | lat | long .....
クエリを実行すると。
Session.createSQLQuery(this.query)
.addEntity("p", Product.class)
.addEntity("w", Warehouse.class).list();
したがって、すべての結果に対して、Product object
とWarehouse object
を含むオブジェクトを取得します。
これは予想されます。問題は、hibernateが製品のIDと名前をウェアハウスオブジェクトのIDと名前のプロパティに割り当てることです。ウェアハウスプロジェクトの作成に関しては、結合結果の最初の2列がオーバーライディングしているように見えます。 Productオブジェクトには、常に正しいデータが含まれています。
この問題を回避する方法を見つけて、正しいウェアハウスデータを表すid列とname列を見つけるための提案をいただければ幸いです。
前もって感謝します。
{}形式を使用して、列名の重複に関する問題を回避します。
SELECT {p.*}, {w.*} FROM product p INNER JOIN warehouse w ON p.wid = w.id
Hibernateリファレンスドキュメント 、セクション18.1.4から。複数のエンティティを返す:
これまで、結果セットの列名は、マッピングドキュメントで指定された列名と同じであると想定されていました。同じ列名が複数のテーブルに表示される可能性があるため、これは複数のテーブルを結合するSQLクエリでは問題になる可能性があります。
次のクエリでは、列エイリアスの挿入が必要です(ほとんどの場合失敗します)。
sess.createSQLQuery("SELECT c.*, m.* FROM CATS c, CATS m WHERE c.MOTHER_ID = c.ID")
.addEntity("cat", Cat.class)
.addEntity("mother", Cat.class)
このクエリは、行ごとに2つのCatインスタンス(猫とその母親)を返すことを目的としていました。ただし、名前の競合があるため、クエリは失敗します。インスタンスは同じ列名にマップされます。また、一部のデータベースでは、返される列エイリアスは「c.ID」、「c.NAME」などの形式である可能性が高く、マッピングで指定された列(「ID」および「NAME」)と等しくありません。 。
次のフォームは、列名の重複に対して脆弱ではありません。
sess.createSQLQuery("SELECT {cat.*}, {mother.*} FROM CATS c, CATS m WHERE c.MOTHER_ID = c.ID")
.addEntity("cat", Cat.class)
.addEntity("mother", Cat.class)
このクエリは次を指定しました:
sQLクエリ文字列。Hibernateが列エイリアスを挿入するためのプレースホルダーを使用して、クエリによって返されるエンティティを
{cat.*}
および{mother.*}
上記で使用されている表記は、「すべてのプロパティ」の省略形です。
エンティティが同じクラスに属していない場合のサンプルを次に示します。
public static void main(String[] args) {
Session sess = NewHibernateUtil.getSessionFactory().openSession();
SQLQuery q = null;
String query = "select a.*, u.* from user u, account a where a.iduser=u.iduser";
q = sess.createSQLQuery(query);
q.addEntity(User.class);
q.addEntity(Account.class);
List lst = q.list();
System.out.println("" + lst.size());
for (int i = 0; i < lst.size(); i++) {
System.out.println(((Object[]) lst.get(i))[0]); //account bean, actually this is in reverse order - so this is user bean
System.out.println(((Object[]) lst.get(i))[1]); //user bean & this account bean
}
sess.close();
}
Coding_idiotが言ったように、クエリ結果のエンティティは異なるクラスからのものであるため、おそらくわからない場合は、要素内のすべてのオブジェクトにアクセスできます。
List<Object>
_を作成します(例:List<Object> objs = (List<Object>)query.getResultList();
)for (Object obj : objs){...}
)List<Object>
_のすべての要素には_Object[]
_があるため、すべての要素をこのクラスにキャストします(例:Object[] o = (Object[]) obj;
)o[4]
_)コードサンプル:
_ Query query = JPA.em().createNativeQuery("SELECT * FROM product p
INNER JOIN warehouse w ON p.wid = w.id");
/* I suppose that it return fields sorted by entities and field in
database:
*
* 0: product.id | 1: product.name | 2: product.wid | 3: product.price | 4: product.stock | n-1: product.N-1Field
* n: warehouse.id | n+1: name | n+2: warehouse.city | n+3: warehouse.lat | n+4: warehouse.long | m-1: warehouse.M-1Field
*
* Join result: id | name | wid | price | stock | ... | id | name | city | lat | long | ...
*/
List<Object> objs = (List<Object>)query.getResultList();
for (Object obj : objs) {
Object[] o = (Object[]) obj;
String productId = String.valueOf(o[0]);
String productName = String.valueOf(o[1]);
String productWid = String.valueOf(o[2]);
... }
_