Let's see the source snapshot first:
Code:
public boolean contains(Object object) {
if (object instanceof HibernateProxy) {
return HibernateProxyHelper.getLazyInitializer( (HibernateProxy) object ).getSession()==this;
}
else {
return entityEntries.containsKey(object);
}
}
Above is catched from SessionImpl.
My problem is that I would like to reattach a seesion(opened in the second request-response cycle) to an entity(queried out in the first request-respponse cycle). But before I reattach a session, I think it is necessary to test if this entity is already associated with a session.
Here the problem comes, actually my entity is an instance of HibernateProxy and it is still associated with a first session opened in the first request-response cycle. But I believe I already close the first session and set the threadlocal to null in Servlet Filter. So this session should be supposed no loger existed. But actually it is still referenced by this entity, right? Why I said so, it is because the
Code:
HibernateProxyHelper.getLazyInitializer( (HibernateProxy) object ).getSession()
returns a session which is supposed to be closed and should be detached from the entity. But since the old session is returned and absolutely not equals to the new session, so it return false.
Because contains() return false, I tried to reattach a new session to this entity. And then it results in this exception:
Code:
net.sf.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: 1, of class: kk.Employee
Is the statement above correct? Or something I missed, so resulted in such a problem?
Below is my servlet filter to manage session, for your reference:
Code:
public class KKFilter implements Filter {
private static ThreadLocal hibernateSession = new ThreadLocal();
private static SessionFactory sessionFactory;
static {
Configuration cfg;
try {
cfg = new Configuration().configure();
sessionFactory = cfg.buildSessionFactory();
}
catch (HibernateException e) {
throw new RuntimeException("Fail to configure hibernate", e);
}
}
public static Session getSession() {
Session s = (Session) hibernateSession.get();
if (s == null || !s.isOpen()) //This is usually used without Servlet
s = initSession();
return s;
}
public void init(FilterConfig arg0) throws ServletException {
// empty
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
assert hibernateSession.get() == null;
try {
Session session = initSession();
String result = null;
try {
chain.doFilter(request, response);
}
finally {
session = (Session) hibernateSession.get();
if (session != null)
session.close();
hibernateSession.set(null);
}
}
catch (HibernateException e) {
throw new RuntimeException("Fail to close hibernate session", e);
}
}
public void destroy() {
}
private static Session initSession() {
Session session;
try {
session = sessionFactory.openSession();
hibernateSession.set(session);
return session;
}
catch (HibernateException e) {
throw new RuntimeException("Fail to open hibernate session.");
}
}
}
[/code]