2-4 チケット情報を表示しよう

この節からはO/RマッッピングツールのHibernateを使用したサンプルが掲載されています。マッピングの設定が面倒くさそうですが、それさえやってしまえば、データクラス自体はすっきりします。Middlegenというツールも興味深いので、近々試してみようと思っています。
Springの設定ファイルで、sessionFactoryのhibernate.show_sqlプロパティをtrueにしているため、サンプルを動かすと実行されたSQL文が表示されます。そのため、「予約済みのチケットを取得する」際に、どのようなSQL文が実行されて、どのようにオブジェクトが生成されるかを追ってみました。
まず、TicketDaoImplオブジェクトから、userIdが渡された上で、以下のような呼び出しが行なわれます。

public class TicketDaoImpl extends HibernateDaoSupport implements TicketDao {

    public List getBookedTicketList(Integer userId) {

        return getHibernateTemplate().find(
                " FROM Ticket AS ticket INNER JOIN FETCH ticket.event AS event "
                        + " INNER JOIN FETCH ticket.rank AS rank WHERE ticket.reservation.user.userId = ? ", userId);
    }
}

この結果、TicketクラスのオブジェクトがList形式で返ってきます。Ticketクラスには、Rank/Eventクラスのメンバー変数を保持していて、HQLでINNER FETCHしているので、それらも同時に生成されるようです。それをやるために、以下のようなSQL文が実行されていました。

select 
  ticket0_.TICKET_ID as TICKET1_3_0_, 
  event1_.EVENT_ID as EVENT1_0_1_, 
  rank2_.RANK_ID as RANK1_1_2_, 
  ticket0_.RANK_ID as RANK2_3_0_, 
  ticket0_.EVENT_ID as EVENT3_3_0_, 
  event1_.NAME as NAME0_1_, 
  event1_.DATE as DATE0_1_, 
  rank2_.NAME as NAME1_2_, 
  rank2_.PRICE as PRICE1_2_, 
  rank2_.EVENT_ID as EVENT4_1_2_ 
from 
  ticket ticket0_ 
    inner join event event1_ on ticket0_.EVENT_ID=event1_.EVENT_ID 
    inner join rank rank2_ on ticket0_.RANK_ID=rank2_.RANK_ID, 
  reservation reservatio3_ 
where 
  ticket0_.TICKET_ID=reservatio3_.RESERVATION_ID and 
  reservatio3_.USER_ID=?

HQLでticket.reservation.user.userIdとやると、それについても自動的に外部結合してくれています。さらにこのあと、取得した件数分だけ、別のSQL文が実行されていました。

select 
  reservatio0_.RESERVATION_ID as RESERVAT1_2_4_, 
  reservatio0_.TIMESTAMP as TIMESTAMP2_4_, 
  reservatio0_.USER_ID as USER3_2_4_, 
  ticket1_.TICKET_ID as TICKET1_3_0_, 
  ticket1_.RANK_ID as RANK2_3_0_, 
  ticket1_.EVENT_ID as EVENT3_3_0_, 
  rank2_.RANK_ID as RANK1_1_1_, 
  rank2_.NAME as NAME1_1_, 
  rank2_.PRICE as PRICE1_1_, 
  rank2_.EVENT_ID as EVENT4_1_1_, 
  event3_.EVENT_ID as EVENT1_0_2_, 
  event3_.NAME as NAME0_2_, 
  event3_.DATE as DATE0_2_, 
  user4_.USER_ID as USER1_4_3_, 
  user4_.NAME as NAME4_3_ 
from 
  reservation reservatio0_ 
    inner join ticket ticket1_ on reservatio0_.RESERVATION_ID=ticket1_.TICKET_ID 
    left outer join rank rank2_ on ticket1_.RANK_ID=rank2_.RANK_ID 
    left outer join event event3_ on ticket1_.EVENT_ID=event3_.EVENT_ID 
    left outer join user user4_ on reservatio0_.USER_ID=user4_.USER_ID 
where 
  reservatio0_.RESERVATION_ID=?

これは、Ticketクラスのメンバー変数であるReservationクラスのオブジェクトを生成するのに使われていて、なぜこれが実行されたかというと、Ticket.hbm.xmlの中で、

    <!-- bi-directional one-to-one association to Reservation -->
    <one-to-one
        name="reservation"
        class="model.Reservation"
        outer-join="auto"
    />

というように、outer-joinプロパティをautoに指定しているからなのではないかと考えられます。
この二つ目のSQL結果は、一つ目のSQL結果と重複している情報も取得しているような気がして、無駄な処理のような感じもしましたが、いずれにせよ、もうしばらくHibernateの作法を学んでからではないと何とも言えません。