Гибернация с многопоточностью в приложении Swing - PullRequest
2 голосов
/ 24 января 2012

Я столкнулся с проблемой гибернации с многопоточностью.

Я разрабатываю свинг-приложение, в котором есть несколько классов POJO. Отношения между классами: Категория имеет набор протоколов, Протокол имеет набор Step, Step имеет набор Mode. Все коллекции загружаются лениво с fetch = FetchType.LAZY . Я поддерживаю один сеанс для приложения. После получения списка всех категорий мне нужно запустить несколько потоков, чтобы выполнить некоторые операции со списком категорий. Здесь я получаю LazyInitializationException. Тестовый код выглядит следующим образом:

</p>

<pre><code>final List&lt;Category> cats = protocolDao.getCategoryList();
for (int i = 0; i < 10; i++) {
new Thread("THREAD_" + i) {
    public void run() {
    try {
        for (Category category : cats) {
        Set&lt;Protocol> protocols = category.getProtocols();
            for (Protocol protocol : protocols) {
            Set&lt;Step> steps = protocol.getStep();
            for (Step step : steps) {
                step.getModes());
            }
            }
        }
        System.out.println(Thread.currentThread().getName()+"SUCCESS"  ;
        } catch (Exception e) {
        System.out.println("EXCEPTION ON " + Thread.currentThread().getName());
        }
    };
    }.start();
}

Метод дао выглядит следующим образом:

</p>

<pre><code>public List&lt;Category> getCategoryList() throws ProtocolException {
    try {
        Transaction transaction = session.beginTransaction();
    List list = session.createCriteria(Category.class)
        .setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY)
        .addOrder(Order.asc("categoryposition")).list();
    transaction.commit();
    return list;
    } catch (Exception e) {
       throw new ProtocolException(e);
    }
}

Когда я пытаюсь запустить приведенный выше код, я получаю следующее исключение для некоторых потоков:

<code>
SEVERE: illegal access to loading collection
org.hibernate.LazyInitializationException: illegal access to loading collection
    at org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:363)
    at org.hibernate.collection.AbstractPersistentCollection.read(AbstractPersistentCollection.java:108)
    at org.hibernate.collection.PersistentSet.toString(PersistentSet.java:332)
    at java.lang.String.valueOf(String.java:2826)
    at java.lang.StringBuilder.append(StringBuilder.java:115)
    at com.mycomp.core.protocol.dao.test.TestLazyLoading$1.run(TestLazyLoading.java:76)

Так что некоторые задачи не выполнены. Я не могу избежать нескольких потоков для работы с одним и тем же списком категорий (он отлично работает с одним потоком). Каждый поток требует выполнить свою задачу. База данных слишком велика, чтобы избежать отложенной загрузки. Кто-нибудь может мне помочь, как я смогу работать с несколькими потоками с одним и тем же списком категорий?

1 Ответ

2 голосов
/ 24 января 2012

Вы должны убедиться, что только поток, который получает ваши объекты, использует их.Если у вас есть идентификаторы get и get по методу id или аналогичному:

final int[] catIds = protocolDao.getCategoryIds();
for (int i : catIds) {
  new Thread("THREAD_" + i) {
    public void run() {
      Category category = protocolDao.getCategory(i);
      Set<Protocol> protocols = category.getProtocols();
      for (Protocol protocol : protocols) {
        Set<Step> steps = protocol.getStep();
          for (Step step : steps) {
            step.getModes());
          }
      }
    };
  }.start();
}
...