EclipseLink JPA @OneToMany List is not same in differernt request of same session in Jesery REST -
i have 2 entities people , story. post story , check stories, returns different story list occasionally. mean, usr.stories.hashcode() not same in differernt request same user. database table correct, confused. checked out hibernate reference better details, didn't @ all.
model class:
@mappedsuperclass public class people{ @id @generatedvalue(strategy = identity) @column(name = "id", unique = true, nullable = false) public integer id; @orderby(value = "id desc") @onetomany(cascade = cascadetype.all, fetch = fetchtype.lazy, mappedby = "people") public list<story> stories = new linkedlist<story>(); public people(){ } } @mappedsuperclass public class story{ @id @generatedvalue(strategy = identity) @column(name = "id", unique = true, nullable = false) public integer id; @manytoone(fetch = fetchtype.lazy) @joincolumn(name = "people_id") public people people; @column(name = "story", nullable = false) public string story; public story(string story){ this.story = story; } } rest class:
@path("/story") public class storyrs { @post public streamingoutput create(final @context httpservletrequest req, final string story) throws ioexception{ return new streamingoutput() { @override public void write(outputstream os) { httpsession hs = req.getsession(false); if (hs != null && story != null && story.trim().length() > 0) { integer uid = (integer) hs.getattribute("uid"); people usr = uid != null ? peopledao.findbyid(uid) : null; if (usr != null) { story obj = new story(story); entitymanagerhelper.begintransaction(); storydao.save(obj); entitymanagerhelper.commit(); os.write(obj.id); } } os.close(); } }; } @get public streamingoutput create(final @context httpservletrequest req) throws ioexception{ return new streamingoutput() { @override public void write(outputstream os) { httpsession hs = req.getsession(false); if (hs != null && story != null && story.trim().length() > 0) { integer uid = (integer) hs.getattribute("uid"); people usr = uid != null ? peopledao.findbyid(uid) : null; if (usr != null && usr.stories != null && usr.stories.size()>0) { os.write(usr.stories...); } } os.close(); } }; } } peopledao:
public class peopledao{ @override public void save(people entity) { try { getentitymanager().persist(entity); } catch (runtimeexception re) { entitymanagerhelper.log("save failed", level.severe, re); throw re; } } @override public void delete(people entity) { try { entity = getentitymanager().getreference(people.class, entity.getid()); getentitymanager().remove(entity); } catch (runtimeexception re) { entitymanagerhelper.log("delete failed", level.severe, re); throw re; } } @override public people update(people entity) { try { people result = getentitymanager().merge(entity); return result; } catch (runtimeexception re) { entitymanagerhelper.log("update failed", level.severe, re); throw re; } } @override public people findbyid(integer id) { try { people instance = getentitymanager().find(people.class, id); return instance; } catch (runtimeexception re) { entitymanagerhelper.log("find failed", level.severe, re); throw re; } } storydao:
public class storydao{ @override public void save(story entity) { try { getentitymanager().persist(entity); } catch (runtimeexception re) { entitymanagerhelper.log("save failed", level.severe, re); throw re; } entity.people.stories.add(0, entity); } @override public void delete(story entity) { try { entity = getentitymanager().getreference(story.class, entity.getid()); getentitymanager().remove(entity); } catch (runtimeexception re) { entitymanagerhelper.log("delete failed", level.severe, re); throw re; } entity.people.stories.remove(entity); } @override public story update(story entity) { try { story result = getentitymanager().merge(entity); return result; } catch (runtimeexception re) { entitymanagerhelper.log("update failed", level.severe, re); throw re; } } @override public story findbyid(integer id) { try { story instance = getentitymanager().find(story.class, id); return instance; } catch (runtimeexception re) { entitymanagerhelper.log("find failed", level.severe, re); throw re; } } entitymanagerhelper:
public class entitymanagerhelper { private static final entitymanagerfactory emf; private static final threadlocal<entitymanager> threadlocal; private static final logger logger; static { emf = persistence.createentitymanagerfactory("db"); threadlocal = new threadlocal<entitymanager>(); logger = logger.getlogger("db"); logger.setlevel(level.all); } public static entitymanager getentitymanager() { entitymanager manager = threadlocal.get(); if (manager == null || !manager.isopen()) { manager = emf.createentitymanager(); threadlocal.set(manager); } return manager; } public static void closeentitymanager() { entitymanager em = threadlocal.get(); threadlocal.set(null); if (em != null) em.close(); } public static void begintransaction() { getentitymanager().gettransaction().begin(); } public static void commit() { getentitymanager().gettransaction().commit(); } public static void rollback() { getentitymanager().gettransaction().rollback(); } public static query createquery(string query) { return getentitymanager().createquery(query); } thanks lot response
here's problem
public static entitymanager getentitymanager() { entitymanager manager = threadlocal.get(); if (manager == null || !manager.isopen()) { manager = emf.createentitymanager(); threadlocal.set(manager); } return manager; } entitymanager's supposed short-lived objects. they're cheap make , cheap destroy. explains why getting inconsistent results. entitymanagers have internal cache surprisingly aggressive.
the rule working em's "one entitymanager per transaction."
change code new em every time , problems go away.
Comments
Post a Comment