JPQLではFETCH JOINする関連Entityに別名をつけられない?
SELECT mtoo FROM ManyToOneOwner mtoo INNER JOIN FETCH mtoo.oneToManyInverse otmi WHERE otmi.id <= 10
こんなJPQLをHibernateで実行すると
Hibernate: select manytooneo0_.id as id2_0_, onetomanyi1_.id as id3_1_, manytooneo0_.name as name2_0_, manytooneo0_.height as height2_0_, manytooneo0_.weight as weight2_0_, manytooneo0_.email as email2_0_, manytooneo0_.hireFiscalYear as hireFisc6_2_0_, manytooneo0_.birthday as birthday2_0_, manytooneo0_.birthTime as birthTime2_0_, manytooneo0_.birthTimestamp as birthTim9_2_0_, manytooneo0_.employmentDate as employm10_2_0_, manytooneo0_.weddingDay as weddingDay2_0_, manytooneo0_.bloodType as bloodType2_0_, manytooneo0_.employeeStatus as employe13_2_0_, manytooneo0_.salaryRate as salaryRate2_0_, manytooneo0_.retired as retired2_0_, manytooneo0_.version as version2_0_, manytooneo0_.oneToManyInverse_id as oneToMa17_2_0_, manytooneo0_.subOneToManyInverse_id as subOneT18_2_0_, onetomanyi1_.name as name3_1_, onetomanyi1_.version as version3_1_ from ManyToOneOwner manytooneo0_ inner join OneToManyInverse onetomanyi1_ on manytooneo0_.oneToManyInverse_id=onetomanyi1_.id where onetomanyi1_.id<=10
こんなSQLを出力します(DialectはDerbyで試してます)が、TopLinkだと・・・
Caused by: Exception [TOPLINK-8025] (Oracle TopLink Essentials - 9.1 (Build b29)): oracle.toplink.essentials.exceptions.EJBQLException
Exception Description: line 1, column 77: Syntax error parsing the query [SELECT mtoo FROM ManyToOneOwner mtoo INNER JOIN FETCH mtoo.oneToManyInverse otmi WHERE otmi.id <= 10], unexpected token [otmi].
ぐっ・・・FETCH JOINするEntityに別名つけられないのか・・・
ってことは、INNER JOIN FETCH して、更にWHERE句で条件つけることは出来ないので、別にINNER JOINする必要があるってことか・・・まぁたしかに、FETCH JOINはどちらかというとフラグみたいなもんなので、1対多な関連に対して条件つけたりすると、元々の関連定義からしても妙になってしまうし、その理由はわかるのですが・・・せめて多対1や1対1な関連には別名が使えないと、かなり使い辛い・・・
HQLは機能的には弱くても、結構SQL感覚で使っていけるのですが、JPQL(というかTopLink)は同じ感覚では使えないですね。FETCH JOINはLAZYロードのコントロールに必須な機能なので、ここの使い勝手が悪いのは、正直言って致命的です・・・
(追記)
SELECT mtoo FROM ManyToOneOwner mtoo INNER JOIN FETCH mtoo.oneToManyInverse WHERE mtoo.oneToManyInverse.id <= 10
・・・これならTopLinkでも通りました。多分N対1な関連じゃないと駄目っぽいけど。(試してみたらやっぱりN対1じゃないと駄目でした。そしてHibernateではどれでもOKでした。)
ぬ・・・・まぁ出来ないよりはマシか。