Hibernate version:
3.1.2
Mapping documents:
Code between sessionFactory.openSession() and session.close():
Spring Hibernate Temple wird verwendet
bzw. für die Long Session:
Code:
import java.io.IOException;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.FlushMode;
import org.hibernate.classic.Session;
import org.hibernate.context.ManagedSessionContext;
import org.hibernate.SessionFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.dao.DataAccessResourceFailureException;
import org.springframework.orm.hibernate3.SessionFactoryUtils;
import org.springframework.orm.hibernate3.SessionHolder;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import org.springframework.web.filter.OncePerRequestFilter;
public class OpenSessionInJobBinder {
protected final Log logger = LogFactory.getLog(getClass());
public static final String DEFAULT_SESSION_FACTORY_BEAN_NAME = "sessionFactory";
private String sessionFactoryBeanName = DEFAULT_SESSION_FACTORY_BEAN_NAME;
private boolean singleSession = true;
public static final String HIBERNATE_SESSION_KEY = "hibernateSession";
public static final String END_OF_CONVERSATION_FLAG = "endOfConversation";
boolean participate = false;
public void setSessionFactoryBeanName(String sessionFactoryBeanName) {
this.sessionFactoryBeanName = sessionFactoryBeanName;
}
protected String getSessionFactoryBeanName() {
return sessionFactoryBeanName;
}
public void setSingleSession(boolean singleSession) {
this.singleSession = singleSession;
}
protected boolean isSingleSession() {
return singleSession;
}
public void doBind(Session session, ApplicationContext ctx) {
SessionFactory sessionFactory = lookupSessionFactory(ctx);
ManagedSessionContext.bind(session);
participate = false;
if (isSingleSession()) {
if (TransactionSynchronizationManager.hasResource(sessionFactory)) {
participate = true;
} else {
logger.info("Opening single Hibernate Session in OpenSessionInJobBinder");
TransactionSynchronizationManager.bindResource(sessionFactory, new SessionHolder(session));
}
} else {
if (SessionFactoryUtils.isDeferredCloseActive(sessionFactory)) {
participate = true;
} else {
SessionFactoryUtils.initDeferredClose(sessionFactory);
}
}
}
public Session doUnBind(Session session, ApplicationContext ctx, boolean end) {
SessionFactory sessionFactory = lookupSessionFactory(ctx);
try {
session = ManagedSessionContext.unbind(sessionFactory);
}
finally {
SessionHolder sessionHolder = (SessionHolder) TransactionSynchronizationManager.getResource(sessionFactory);
if (end) {
if (isSingleSession()) {
// single session mode
TransactionSynchronizationManager.unbindResource(sessionFactory);
try {
closeSession(session, sessionFactory);
} catch (RuntimeException ex) {
}
} else {
SessionFactoryUtils.processDeferredClose(sessionFactory);
}
session = null;
} else {
}
}
return session;
}
protected SessionFactory lookupSessionFactory(ApplicationContext ctx) {
return (SessionFactory) ctx.getBean(getSessionFactoryBeanName(), SessionFactory.class);
}
protected void closeSession(Session session, SessionFactory sessionFactory) {
SessionFactoryUtils.releaseSession(session, sessionFactory);
}
}
The generated SQL (show_sql=true):
mySQL 5.0
,
der Ablauf ist der folgende:
Laden eines Users, lazy loading der PicLibrarays objectes dieses users.
übergeben des users und des PicLib und des SESSION objectes an einen neuen thread,
aufrufen von doBind (siehe oben) mit der übergebenen Session.
lazy loading von Objecten der Piclib,
soweit funktioniert noch alles,
jetzt aber wird ein Attribut der PicLib geändert, das agnze soll dann über das SpringHibernate Template, mittels SaveOrUpdate gespeichert werden.
das geht aber nicht, weil ich jetzt immer eine expetion bekomme das ein anderes Objekt mit dem gleichen identifier bereits in der Session drin ist?
ja super das ist ja eigentlich mein objekt, halt genau das gleiche nur eben ohne die Änderung des einen Attributes.
habe schon alles mögliche ausprobiert und finde einfach keinen weg das ich dieses objekt jetzt speichern kann? hat da jemand eine idee bzw hinweis was ich falsch mache?
das muss doch irgendwie gehen???
Vielen Dank schon mal.
mfg Gideon