java - Lazy loading property and session.get problem -
in hibernate have 2 classes following classes jpa mapping:
package com.example.hibernate import javax.persistence.entity; import javax.persistence.fetchtype; import javax.persistence.generatedvalue; import javax.persistence.generationtype; import javax.persistence.id; import javax.persistence.manytoone; @entity public class foo { private long id; private bar bar; @id @generatedvalue(strategy = generationtype.auto) public long getid() { return id; } public void setid(long id) { this.id = id; } @manytoone(fetch = fetchtype.lazy) public bar getbar() { return bar; } public void setbar(bar bar) { this.bar = bar; } } package com.example.hibernate import javax.persistence.generatedvalue; import javax.persistence.generationtype; import javax.persistence.id; public class bar { private long id; private string title; @id @generatedvalue(strategy = generationtype.auto) public long getid() { return id; } public void setid(long id) { this.id = id; } public string gettitle() { return title; } public void settitle(string title) { this.title = title; } }
now when load database object class foo using session e.g:
foo foo = (foo)session.get(foo.class, 1 /* or other id exists in db*/); bar member of foo proxy object (in our case javassist proxy can cglib 1 depending on bytecode provider use), not initialized. if use session.get fetch bar object member of foo class loaded (we in same session), hibernate not issue db query , fetches object session (first level) cache. problem proxy bar class not initialized , trying call object getid() return 0, , gettitle() return null. our current solution pretty ugly , checks if object returned proxy here code (form generic dao implementation):
@suppresswarnings("unchecked") @override @transactional(readonly = true) public <t extends ientity> t get(class<t> clazz, serializable primarykey) throws dataaccessexception { t entity = (t) currentsession().get(clazz, primarykey); if (entity != null) { if (log.iswarnenabled()) { log.warn("object not found class " + clazz.getname() + " primary key " + primarykey); } } else if (entity instanceof hibernateproxy){ // todo: force initialization due hibernate bug hibernateproxy proxy = (hibernateproxy)entity; if (!hibernate.isinitialized(proxy)) { hibernate.initialize(proxy); } entity = (t)proxy.gethibernatelazyinitializer().getimplementation(); } return entity; }
is there better way this, couldn't find solution in hibernate forum, , didn't find issue in hibernate's jira.
note: cannot use foo.getbar() (which initialize proxy properly) bar class object, because session.get operation fetch bar object not know (or care matter) bar class lazy member of foo object fetched.
i had similar problem:
- i did session.save(nastyitem) save object session. however, did not fill in property buyer mapped update="false" insert="false" (this happens lot when have composed primary key, map many-to-one's insert="false" update="false")
- i query load list of items, , item saved, happens part of result set
- now goes wrong? hibernate sees item in cache, , hibernate not replace (probably not break earlier reference nastyitem) newly loaded value, uses nastyitem have put session cache myself. worse, lazy loading of buyer broken: contains null.
to avoid these session issues, flush , clear after save, merge, update or delete. having solve these nasty problems takes of time :-(
Comments
Post a Comment