Java 非法尝试将集合与两个打开的会话关联
我正在尝试将一个pojo添加到另一个pojo中的集合中。我敢肯定,我在某些方面犯了一个非常愚蠢的错误,但我不知道如何解决它 我有一个pojo LookupTable,其中包含列列表:Java 非法尝试将集合与两个打开的会话关联,java,hibernate,spring,transactions,Java,Hibernate,Spring,Transactions,我正在尝试将一个pojo添加到另一个pojo中的集合中。我敢肯定,我在某些方面犯了一个非常愚蠢的错误,但我不知道如何解决它 我有一个pojo LookupTable,其中包含列列表: public class LookupTable { private long id; // More properties go here... private List<Column> columns; public void addColumn(Column column) {
public class LookupTable {
private long id;
// More properties go here...
private List<Column> columns;
public void addColumn(Column column) {
this.columns.add(column);
}
// More methods go here...
}
变量lookupTableDao在这里指的是一个简单的DAO类,它扩展了HibernateDaoSupport
我得到的错误是:
org.hibernate.HibernateException: Illegal attempt to associate a collection with two open sessions
at org.hibernate.collection.AbstractPersistentCollection.setCurrentSession(AbstractPersistentCollection.java:410)
at org.hibernate.event.def.OnUpdateVisitor.processCollection(OnUpdateVisitor.java:43)
at org.hibernate.event.def.AbstractVisitor.processValue(AbstractVisitor.java:101)
at org.hibernate.event.def.AbstractVisitor.processValue(AbstractVisitor.java:61)
at org.hibernate.event.def.AbstractVisitor.processEntityPropertyValues(AbstractVisitor.java:55)
at org.hibernate.event.def.AbstractVisitor.process(AbstractVisitor.java:123)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performUpdate(DefaultSaveOrUpdateEventListener.java:293)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsDetached(DefaultSaveOrUpdateEventListener.java:223)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:89)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:70)
at org.hibernate.impl.SessionImpl.fireSaveOrUpdate(SessionImpl.java:507)
at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:499)
at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:495)
at com.foo.AbstractDao.saveOrUpdate(AbstractDao.java:29)
at com.foo.LookupTableManager.addColumnToTable(LookupTableManager.java:338)
... etc ...
好的,我明白我得到的基本信息。但我不明白的是第二节课在哪里。。。。有人能帮我吗
我使用的是Hibernate 3.2.6.ga、Spring 2.5.5和Tomcat 6.0我猜
lookupTableDao.findById
调用是在一个会话中获取对象,但是lookupTableDao.save或Update
是另一个-如何通过Spring获取会话
对象
列
对象来自何处-它已经在DB上了还是新的?原来我根本没有事务。我在另一个配置文件中使用了几乎相同的事务配置
那里的切入点也被称为“管理者”,所以我的顾问在这里引用了另一个文件中的切入点
重命名切入点解决了我的问题。问题在于视图中打开的会话筛选器映射。 它正在getSession上创建会话 另一个在保存 只能将singleSession更改为false
默认值为true显然,使用merge可能会解决问题
myInstance = (myInstanceClass) Session.merge(myInstance);
如果您只想在代码的一部分上进行事务处理,可以使用如下方式:
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
在课堂上:
@Autowired private SessionFactory sessionFactory;
稍后,围绕应在同一事务中执行操作的代码:
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
Stuff stuff = getStuff();
manipulate(stuff);
send(stuff);
save(stuff);
tx.commit();
在一些长时间运行的批处理作业中,我在循环中使用了它。我的以下代码也有同样的问题: 我想更新某个实体存储。我正在从该方法检索它:
@Override
public Store getStoreByStoreId(final long storeId) {
getHibernateTemplate().execute(new HibernateCallback<Store>() {
@Override
public StoredoInHibernate(Session session) throws HibernateException, SQLException {
return (Store) session.createCriteria(Store.class)
.add(Restrictions.eq(Store.PROP_ID, storeId))
.uniqueResult();
}
});
}
@覆盖
公共存储getStoreByStoreId(最终长存储ID){
getHibernateTemplate().execute(新的HibernateCallback()){
@凌驾
public StoredoInHibernate(会话会话)抛出HibernateeException、SQLException{
return(Store)session.createCriteria(Store.class)
.add(Restrictions.eq(Store.PROP_ID,storeId))
.uniqueResult();
}
});
}
然后,我用以下方法更新存储:
@Override
public void updateStoreByStoreId(final long storeId) {
getHibernateTemplate().execute(new HibernateCallback<Void>() {
@Override
public Void doInHibernate(Session session) throws HibernateException, SQLException {
Store toBeUpdated = getStoreByStoreId(storeId);
if (toBeUpdated != null){
// ..change values for certain fields
session.update(toBeUpdated);
}
return null;
}
});
}
@覆盖
public void updatestrobystoreid(最终长存储ID){
getHibernateTemplate().execute(新的HibernateCallback()){
@凌驾
public Void doInHibernate(会话会话)抛出HibernateeException、SQLException{
Store toBeUpdated=getStoreByStoreId(storeId);
如果(toBeUpdated!=null){
//..更改某些字段的值
会话。更新(待更新);
}
返回null;
}
});
}
事实证明,我得到了“非法尝试…”错误,因为get方法的第一个会话没有关闭,并且我正试图用另一个会话更新存储。我的解决方案是在update方法中移动检索要更新的存储的调用
@Override
public void updateStoreByStoreId(final long storeId) {
getHibernateTemplate().execute(new HibernateCallback<Void>() {
@Override
public Void doInHibernate(Session session) throws HibernateException, SQLException {
Store toBeUpdated = (Store) session.createCriteria(Store.class)
.add(Restrictions.eq(Store.PROP_ID, storeId))
.uniqueResult();
if (toBeUpdated != null){
// ..change values for certain fields
session.update(toBeUpdated );
}
return null;
}
});
}
@覆盖
public void updatestrobystoreid(最终长存储ID){
getHibernateTemplate().execute(新的HibernateCallback()){
@凌驾
public Void doInHibernate(会话会话)抛出HibernateeException、SQLException{
Store toBeUpdated=(Store)session.createCriteria(Store.class)
.add(Restrictions.eq(Store.PROP_ID,storeId))
.uniqueResult();
如果(toBeUpdated!=null){
//..更改某些字段的值
会话。更新(待更新);
}
返回null;
}
});
}
我使用的是windows server IIS,只是将AppPool管理的管道模式从集成更改为经典解决了我的问题
谢谢[编辑,移动回复评论]:我通过org.springframework.orm.hibernate.support.HibernateDaoSupport的getSession()方法获取会话。这将从当前事务返回会话。。。列对象是新创建的。
@Override
public Store getStoreByStoreId(final long storeId) {
getHibernateTemplate().execute(new HibernateCallback<Store>() {
@Override
public StoredoInHibernate(Session session) throws HibernateException, SQLException {
return (Store) session.createCriteria(Store.class)
.add(Restrictions.eq(Store.PROP_ID, storeId))
.uniqueResult();
}
});
}
@Override
public void updateStoreByStoreId(final long storeId) {
getHibernateTemplate().execute(new HibernateCallback<Void>() {
@Override
public Void doInHibernate(Session session) throws HibernateException, SQLException {
Store toBeUpdated = getStoreByStoreId(storeId);
if (toBeUpdated != null){
// ..change values for certain fields
session.update(toBeUpdated);
}
return null;
}
});
}
@Override
public void updateStoreByStoreId(final long storeId) {
getHibernateTemplate().execute(new HibernateCallback<Void>() {
@Override
public Void doInHibernate(Session session) throws HibernateException, SQLException {
Store toBeUpdated = (Store) session.createCriteria(Store.class)
.add(Restrictions.eq(Store.PROP_ID, storeId))
.uniqueResult();
if (toBeUpdated != null){
// ..change values for certain fields
session.update(toBeUpdated );
}
return null;
}
});
}