Hibernate(十六):DetachedCriteria子クエリとALIAS_TOENTITY
Hibernate(15):Hibernateで記録総数の一つのオタクを求めます。に記述された問題に関連しています。 プロジェクトの中の一つの需要は条件を満たす記録の総数を得るために、最初に思いつきましたのはDetachedCriteriaにset Projection(Projection.projection List().add(Projection s.rowCount())を設定してから、setsResuultTransformer(DetacheCritiaterter.alalalalitititititititityProgeeeeeeemmutotototototototoject.ject.ject.ject.ject)を実行して結果を得るためには、また、Progeeeeeeeeeeeeeemmutotototototo)findByCriteria(d)の時はプログラムカードが必要です。 何回か試してみましたが、いい方法が見つからなかったので、Hibernate(15):Hibernateで記録総数の一つのオタクを求めます。で言っていたような中途半端なリストを採用してからsizeで値を求めます。 試行点1:DetachedCriteriaサブクエリとDetachedCriteria.ALIAS_TOENTITY_MAP時に問題が発生しました コードは以下の通りです
-------------------- 問題の記録が終わって、解決できませんでした。 ここに書いてください。一つは指導をしてほしいです。もう一つは、これからヒベルナに対する認識が深まりましたら、この問題を解決したい時にもう一度考え直す必要がないと思います。
DetachedCriteria hasInfoForCurrentDeptQuery = DetachedCriteria.forClass(ContractTrade.class);
hasInfoForCurrentDeptQuery.setProjection(Projections.projectionList()
.add(Projections.rowCount(), "rowCount"));
//
DetachedCriteria hasImportedQuery = DetachedCriteria.forClass(ContractOtherLink.class);
hasImportedQuery.setProjection(Property.forName("linkContId"));
hasInfoForCurrentDeptQuery.add(Property.forName("contractTradeId").notIn(hasImportedQuery));
hasInfoForCurrentDeptQuery.setResultTransformer(DetachedCriteria.ALIAS_TO_ENTITY_MAP);
Map result = (Map)getHibernateTemplate()
.findByCriteria(hasInfoForCurrentDeptQuery).get(0); // --(1)
このようなコードは(1)で実行されます。プログラムカードはそこで動かなくなりました。DetachedCriteriaサブクエリとDetachedCriteria.ALIAS_が疑われます。TOENTITY_MAPの配合に問題がありましたので、Hbernateで生成されたSQL(生成sql:select count(*)asy 0_from ULOAD CONTRACT ITRADEEWthis_.DEPT ID=24 andthisu.thisu.CaCasosososososon TRACuID notは、またRACTuftCaCaCashshshshshufttCaCaCaCaCaCaCaCaCaCaCashshshshshuftは、CoCoCoCothCashshshshshshshshshshshshuftは、COCOCOCOCOCOCOCOCOCOCOCOCOCOCOCOCOCOCOCOCOCOCOCOCOCOCOCOCOCOCOufufuToadで実行するのは、大丈夫です。結果が出ました。 試行点2:Java+hibernateプログラムでDetachedCriteriaとDetachedCriteria.ALIAS_を試してみます。TOENTITY_MAP協力.試行点1は、最後に生成されたSQLから両者の配合が成功したかどうかを見て、上で生成されたSQLを見て、外周クエリ(select count(*)as y 0_)とサブクエリ(select this 0_.LINKukontuID asy 0_)用の別名はすべてy 0_であり、最終的にHbernateで結果を組み立てる時に別名が同じで問題が発生しますか?そして本物のJavaプログラムを使ってもう一度試してみます。実験コードは以下の通りです。 Session session = sessionFactory.getCurrentSession();
Transaction t = session.beginTransaction();
DetachedCriteria queryCirteriaOuter = DetachedCriteria.forClass(DataDict.class);
queryCirteriaOuter.setProjection(Projections.projectionList()
.add(Projections.rowCount(), "rowCount"));
DetachedCriteria queryCirteriaInner= DetachedCriteria.forClass(DataDictLink.class);
queryCirteriaInner.add(Restrictions.like("tableName", "S_CONTACT"));
queryCirteriaInner.setProjection(Property.forName("columnName"));
queryCirteriaOuter.add(Property.forName("listType").in(queryCirteriaInner));
queryCirteriaOuter.setResultTransformer(DetachedCriteria.ALIAS_TO_ENTITY_MAP);
Criteria executableCriteria = queryCirteriaOuter.getExecutableCriteria(session);
Map map = (Map) executableCriteria.list().get(0);
System.out.println("result: "+map.get("rowCount"));
t.commit();
大丈夫です。結果がよく分かりました。ここで生成したSQLはselect count(*)as y 0_です。from_LOV this_where this_.リスト.Type in(select this_.C.Onum as y 0_from Scuu from Scuris_.where this_.TABLEuNAME like?)別名は大丈夫です。全部y 0_です。これにより、hibernateはResultSetの組み立て時に別名が同じである可能性が排除されました。 トライポイント3:直接JDBCのconnectionで試行1でSQLを生成します。1と2の違いは、試して1で使うのはビューに対応するJava類です。(クラスのContractTradeに対応するUPLLOADC_RACTUITRADE_VIEWはデータベース内の1つのビューです)。2つのjavaクラスを試してみます。データベース内の本当のテーブルに対応しています。hibernateがそのビューにSQLを実行した時に何か問題があったのではないかと思います。すると、次のコードを使ってSQLを直接実行します。何か問題がありますか? SessionFactory sessionFactory = HiberUtil.getSessionFactoryOracle();
Session session = sessionFactory.getCurrentSession();
Transaction t = session.beginTransaction();
Connection conn = session.connection();
String sql = "select count(*) as y0_ from UPLOAD_CONTRACT_ITRADE_VIEW this_ "+
"where this_.DEPT_ID=24 and this_.CONTRACT_ID "+
"not in (select this0__.LINK_CONT_ID as y0_ from CONTRACT_OTHER_LINK this0__)";
PreparedStatement st = conn.prepareStatement(sql);
ResultSet rs = st.executeQuery(sql);
rs.next();
int result = rs.getInt("y0_");
System.out.println("result: "+ result);
t.commit();
まだ大丈夫です テストポイント4:Hibernateのソースから最終的にカードがどこにあるかを確認しました。そしてIDEには何度もブレークポイントを設定しました。最終的にはクラスorg.hibernate.jdbc.AbstractBatchメソッドgetResult Set第一行のResultSet rs=ps.executeQueryを発見しました。一言で押さえました なぜですかコードを追う時にこのpsがhibernate変換されてきたDetachedCriteriaがSQLを生成した後に対応するPreparedSttementであることが分かりました。上記の試みと3のPreparedStatiment=conn.preparementです。似ています。なぜ私の実行ができますか?ここのヒベルナは自動的に生成されたものは失敗しました。-------------------- 問題の記録が終わって、解決できませんでした。 ここに書いてください。一つは指導をしてほしいです。もう一つは、これからヒベルナに対する認識が深まりましたら、この問題を解決したい時にもう一度考え直す必要がないと思います。