13

別のpojoのコレクションにpojoを追加しようとしています。私はどこかで本当にばかげた間違いを犯していると確信していますが、それを解決する方法がわかりません。

列のリストを含むpojoLookupTableがあります。

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...
}

私の休止状態の構成では、次のようになります。

<class name="LookupTable" table="ARR_LOOKUP_TABLE">
  <id name="id" column="ID">
    <generator class="native"/>
  </id>
  <!-- Some properties here -->
  <bag name="columns" cascade="all,delete-orphan" access="field">
    <key column="LOOKUP_TABLE" not-null="true"/>
    <one-to-many class="Column"/>
  </bag>
</class>

<class name="Column" table="ARR_LOOKUP_COLUMN">
  <id name="id" column="ID">
    <generator class="native"/>
  </id>
  <!-- Some properties here -->
</class>

私のSpring設定ファイルには次のものがあります。

<tx:advice id="txAdvice" transaction-manager="txManager">
  <tx:attributes>
    <tx:method name="*" propagation="REQUIRED"/>
  </tx:attributes>
</tx:advice>
<aop:config>
  <aop:pointcut id="managers" expression="execution(public * com.foo.*Manager.*(..))"/>
  <aop:advisor advice-ref="txAdvice" pointcut-ref="managers"/>
</aop:config>

そして最後に、私のマネージャークラス(com.foo.LookupTableManager)内ですべてが失敗するコード:

public void addColumnToTable(Column column, long tableId) {
  LookupTable lookupTable = this.lookupTableDao.findById(tableId);
  lookupTable.addColumn(column);
  this.lookupTableDao.saveOrUpdate(lookupTable);
}

ここでの変数lookupTableDaoは、HibernateDaoSupportを拡張する単純なDAOクラスを参照します。

私が得るエラーは次のとおりです。

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 ...

OK、私は私が得ている基本的なメッセージを理解しています。しかし、私が理解していないのは、2番目のセッションをどこで取得するかです。...誰かがこれを手伝ってくれますか?

Hibernate 3.2.6.ga、Spring 2.5.5、Tomcat6.0を使用しています

4

7 に答える 7

5

取引がまったくなかったことがわかりました。他の構成ファイルの 1 つでほぼ同じトランザクション構成を使用しました。

あちらのポイントカットは「マネージャー」とも呼ばれていたので、ここのアドバイザーは他のファイルのポイントカットを参照していました。

ポイントカットの名前を変更すると、問題が解決しました。

于 2008-10-21T08:40:44.370 に答える
3

私の推測では、lookupTableDao.findById呼び出しは1つのセッションでオブジェクトを取得していますが、これは別のセッションです。Springを介してオブジェクトlookupTableDao.saveOrUpdateを取得するにはどうすればよいですか。Session

オブジェクトはどこColumnから来ていますか?それはすでにDBにありますか、それとも新しいですか?

于 2008-10-21T08:00:46.790 に答える
2

次のコードでも同じ問題がありました。特定のエンティティ ストアを更新したかったのです。私はこのメソッドからそれを取得していました:

@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;
        }
    });
} 

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;
        }
    });
} 
于 2012-04-09T09:13:52.377 に答える
2

問題は、Open Session In ビュー フィルター マッピングにありました。getSession およびその他の保存時にセッションを作成していました。

false デフォルトの true として singleSession のみを変更できます

于 2010-07-16T16:58:13.273 に答える
2

どうやらマージを使用すると、おそらく問題が解決するでしょう

myInstance = (myInstanceClass) Session.merge(myInstance);
于 2011-10-09T15:17:24.230 に答える
0

コードの一部でのみトランザクションが必要な場合は、次のようなものを使用できます。

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();

これは、実行時間の長いバッチ ジョブのループ内で使用します。

于 2011-11-10T20:55:15.573 に答える