2012-03-29 2 views
1

Я пытаюсь подключиться к сеансу объекта из сеанса HTTP, который был первоначально извлечен из БД, я делаю это, вызывая session.lock(object, LockMode.None), и даже если блокировка не каскадирует, это работает правильно для меня, потому что он не нажимает обновления для БД, как merge (блокировка требуется для открытия подробного представления во всплывающем окне, и фактическое сохранение произойдет позднее в главном окне). Теперь, к моему удивлению, я обнаружил, что если моя сущность имеет отношение «один к большому», любые изменения в этой коллекции могут вызвать HibernateException «Объект, связанный с привязкой к объекту, имеет грязную коллекцию».Блокировка Hibernate вызывает исключение для грязной коллекции

Как я могу повторно привязать объекты к сеансу без обновления БД или отбрасывания изменений на объекте?

Вот ситуация, как код

EntityA t = createAnEntityA(); 
    Session sess = factory.openSession(); 
    sess.beginTransaction(); 
    sess.save(t); 
    sess.getTransaction().commit(); 
    sess.close(); 
    // t is now saved on the DB but in dettached state 



    // change a simple property 
    sess = factory.openSession(); 
    sess.beginTransaction(); 
    t.setPropertyB("B"); 
    sess.lock(t, LockMode.NONE); 
    // t is attached again, you won't get LazyInitializationException 
    // by calling its properties, although you have to be careful 
    // because the reattachment does not cascade to children 
    sess.getTransaction().commit(); 
    sess.close(); 
    // no updates went to the DB because setPropertyB was called 
    // when t was still dettached 

    // now change a collection 
    EntityC c = createAnEntityC(); 
    t.getCollectionPropertyC().add(c); 
    sess = factory.openSession(); 
    sess.beginTransaction(); 
    sess.lock(t, LockMode.NONE); 
    // Exception is thrown :-(
    sess.getTransaction().commit(); 
    sess.close(); 
+0

Возможно ли, что ваше решение находится где-то между ответами на этот вопрос: http://stackoverflow.com/questions/912659/what-is-the -proper-way-to-re-attach-detached-objects-in-hibernate –

+0

хорошо слияние или обновление немедленно вносят изменения в БД, и обновление будет потерять изменения в объекте, я хочу, чтобы это было простое повторное подключение, поэтому я 't получить Lazy загрузки исключений, когда я открываю свой подробный вид popp-up – ilcavero

ответ

1

Боюсь, в настоящее время это не представляется возможным, не задев DB. По-видимому, исключение происходит из-за команды блокировки.

Существует такая Jira, которая сообщила об этом.
https://hibernate.atlassian.net/browse/HHH-511

У этого есть 2 исправления, чтобы устранить проблему. Вы можете попробовать эти патчи.

Но если у вас есть проблема только с ленивой загрузкой коллекции, вы можете рассмотреть возможность использования Открыть сеанс в виде. (возможно, не лучший образец, но он может работать на ваш случай)

+0

Ошибка, с которой вы ссылаетесь, действительно не связана с моей потребностью, но после долгих исследований я должен согласиться с вами, что нет возможного пути, еще одна причина нелюбовь Hibernate. Моя работа до сих пор ловит LazyInitialiationException и вызывает блокировку этого улова, таким образом, я только блокирую объект в первый раз, когда он еще не инициализирован и, следовательно, все еще не изменен – ilcavero