문제

나는 다른 pojo의 컬렉션에 pojo를 추가하려고합니다. 나는 줄을 따라 어딘가에 정말 어리석은 실수를하고 있다고 확신하지만 그것을 해결하는 방법을 알 수는 없습니다.

열 목록이 포함 된 Pojo LookUtable이 있습니다.

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>

스프링 구성 파일에는 다음과 같습니다.

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

여기서 변수 Lookupuptabledao는 최대 절전 모드를 확장하는 간단한 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 ...

좋아, 나는 내가받는 기본 메시지를 이해한다. 하지만 내가 이해하지 못하는 것은 내가 두 번째 세션을 어디서 얻는 지입니다 .... 누구든지 이것을 도와 줄 수 있습니까?

Hibernate 3.2.6.ga, Spring 2.5.5 및 Tomcat 6.0을 사용하고 있습니다.

도움이 되었습니까?

해결책

거래가 전혀 없었습니다. 다른 구성 파일 중 하나에서 거의 동일한 트랜잭션 구성을 사용했습니다.

저기의 포인트 컷은 "관리자"라고도 불렸다. 여기서 내 고문은 다른 파일의 포인트 컷을 참조하는 것이었다.

포인트 컷의 이름을 바꾸면 내 문제가 해결되었습니다.

다른 팁

내 생각에 lookupTableDao.findById 통화는 한 세션에서 객체를 얻고 있지만 lookupTableDao.saveOrUpdate 다른 것입니다 - 당신은 어떻게 얻습니까? Session 봄을 통해 물체?

가 어디에 있죠 Column 객체에서 오는 것 - 이미 DB에 있습니까?

문제는 View 필터 매핑의 오픈 세션에 문제가있었습니다. GetSession 및 다른 세이브에 대한 세션을 만들었습니다.

싱글 션 만 거짓 기본값으로 변경할 수 있습니다.

분명히 병합을 사용하면 문제가 해결 될 수 있습니다

myInstance = (myInstanceClass) Session.merge(myInstance);

다음 코드에서도 같은 문제가있었습니다. 특정 엔티티 스토어를 업데이트하고 싶었습니다. 나는이 방법에서 그것을 검색했다.

@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 메소드의 첫 번째 세션이 닫히지 않았기 때문에 "불법 시도 ..."오류가 발생했으며 다른 세션으로 상점을 업데이트하려고했습니다. 저를위한 솔루션은 업데이트 방법에서 업데이트 할 상점 검색 요청을 옮기는 것이 었습니다.

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

코드의 일부보다 거래를 원한다면 다음과 같은 것을 사용할 수 있습니다.

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

나는 이것을 장기 실행되는 배치 작업에서 루프 내부에 사용합니다.

Windows Server IIS를 사용하고 있었고 AppPool 관리 파이프 라인 모드를 통합에서 클래식 해결 된 문제로 변경했습니다.

감사

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top