java - JPA: join tables but after that still makes sequence of queries -
i'm sorry if silly or not complete.
want make 1 query, joining tables @ once.
@namedquery(name="user.findbylogin", query="select u user u " + "left outer join fetch u.userinfo ui " + "left outer join fetch u.freeevents fe " + "left outer join fetch u.paidevents pe " + "left outer join fetch fe.action fea " + "left outer join fetch pe.action pea " + "where u.login = :login")
and works (no errors, no warnings, sql generated), , sql fine, , appropriate data retrieved in mysql console. after makes many requests find actions id, , looks hibernate doesn't know had fetched needed data or have no idea it.
other similar joins 2 tables valid , work expected.
way, freeevent , paidevent @inheritance(strategy=inheritancetype.single_table), differs "rate_type" column. tried both eager , lazy fetch, , hibernate @fetch annotation.
sql itself:
select * #---lots of fields here, valid users user0_ left outer join userinfos userinfo1_ on user0_.`user_info_id`=userinfo1_.id left outer join events freeevents2_ on user0_.id=freeevents2_.`user_id` , freeevents2_.rate_type=1 left outer join freeactions freeaction4_ on freeevents2_.`action_id`=freeaction4_.`id` left outer join events paidevents3_ on user0_.id=paidevents3_.`user_id` , paidevents3_.rate_type=2 left outer join paidactions paidaction5_ on paidevents3_.`action_id`=paidaction5_.`id` user0_.`login`='testuser'
question: problem? classes poorly annotated, or normal hibernate behaviour, find solution?
entities: (without getters, setters , fields not mapped anyone)
@entity @table(name="events") @persistenceunit(name="default") @inheritance(strategy=inheritancetype.single_table) @discriminatorcolumn(name="rate_type", discriminatortype=discriminatortype.integer) public class abstractevent { @id @generatedvalue(strategy=generationtype.identity) private long id; @manytoone(fetch=fetchtype.lazy) private models.user user; @column(name="rate_type", insertable=false, updatable=false) private byte ratetype; } @entity @discriminatorvalue(ratetypehelper.rate_type_free) //it constant of type integer == 1 @persistenceunit(name="default") public class freeevent extends models.events.abstractevent { @onetoone(cascade=cascadetype.persist, fetch=fetchtype.lazy) @joincolumn(name="`action_id`") private freeaction action; public freeaction getaction() { return action; } public void setaction(freeaction action) { this.action = action; } } @entity @discriminatorvalue(ratetypehelper.rate_type_paid) @persistenceunit(name="default") public class paidevent extends models.events.abstractevent { @onetoone(cascade=cascadetype.persist, fetch=fetchtype.lazy) @joincolumn(name="`action_id`") private paidaction action; public paidaction getaction() { return action; } public void setaction(paidaction action) { this.action = action; } }
note: abstract action here not used now. doesn't have fields or methods. empty class futures needs.
@entity @table(name="freeactions") @persistenceunit(name="default") @namedqueries({ @namedquery(name="freeaction.findbyuserid", query="select freeaction " + "left outer join fetch a.event e " + "where e.user = :user_id") }) public class freeaction extends abstractaction { @id @generatedvalue(strategy=generationtype.identity) @column(name="`id`") private long id; @onetoone(mappedby="action", fetch=fetchtype.lazy) private models.events.freeevent event; } @entity @table(name="paidactions") @persistenceunit(name="default") @namedqueries({ @namedquery(name="paidaction.findbyuserid", query="select paidaction " + "left outer join fetch a.event e " + "where e.user = :user_id") }) public class paidaction extends abstractaction { @id @generatedvalue(strategy=generationtype.identity) @column(name="`id`") private long id; @onetoone(mappedby="action", fetch=fetchtype.lazy) private models.events.paidevent event; } @entity @table(name="users") @persistenceunit(name="default") @namedqueries({ @namedquery(name="findfulluserbyid", query="select u user u "+ "left outer join fetch u.userinfo ui " + "where u.id = :id"), @namedquery(name="user.findbyloginpassword", query="select u user u left outer join fetch u.userinfo ui " + "where u.login = :login , u.password = :password"), @namedquery(name="user.findbylogin", query="select u user u " + "left outer join fetch u.userinfo ui " + "left outer join fetch u.freeevents fe " + "left outer join fetch u.paidevents pe " + "left outer join fetch fe.action fea " + "left outer join fetch pe.action pea " + "where u.login = :login") }) public class user { @id @generatedvalue(strategy = generationtype.auto) @column(name="id") private long id; @onetomany(fetch=fetchtype.lazy) @joincolumn(name="`user_id`") private set<freeevent> freeevents; @onetomany(fetch=fetchtype.lazy) @joincolumn(name="`user_id`") private set<paidevent> paidevents; @onetoone(cascade=cascadetype.persist, fetch=fetchtype.lazy) @joincolumn(name="`user_info_id`") private userinfo userinfo; } @entity @table(name="userinfos") @persistenceunit(name="default") public class userinfo { @id @generatedvalue(strategy = generationtype.auto) @column(name="id") private long id; @onetoone(mappedby="userinfo") private user user; }
why u using left outer join? jpa understands set being member of user use join fetch them, albeit lazily when needed?
now fact see more requests may fact have fetchtype.lazy, , @ point invoke 1 of getfreeevents(), getpaidevents(), getuserinfo(), hibernate fire sql query requests retrieve them, @ point not yet loaded.
Comments
Post a Comment