Что делает eclipse при проверке переменных (во время отладки) - PullRequest
2 голосов
/ 21 сентября 2011

У меня есть экземпляр org.hibernate.envers.entities.mapper.relation.lazy.proxy.ListProxy, который вызывает некоторое горе: всякий раз, когда я программно пытаюсь получить к нему доступ, я получаю исключение нулевого указателя (т. Е. Вызов list.size()), но когда я впервые проверяю объект с помощью инспектора переменных Eclipse, я вижу Hibernate генерирует оператор SQL, и список изменяется динамически. Тогда все работает. Как я могу сделать то же самое программно? Я пробовал list.toString(), но это не помогает.

Обновление 1

Не знаю, помогает ли это, но когда я впервые нажимаю на экземпляр списка, я вижу на дисплее:

com.sun.jdi.InvocationException occurred invoking method.

Затем выполняется запрос к базе данных, и когда я нажимаю снова, я получаю правильный .toString() результат.

Обновление 2

Вот исходное исключение, которое я получаю (когда я не проверяю элемент в режиме отладки).

java.lang.NullPointerException
    at org.hibernate.envers.query.impl.EntitiesAtRevisionQuery.list(EntitiesAtRevisionQuery.java:72)
    at org.hibernate.envers.query.impl.AbstractAuditQuery.getSingleResult(AbstractAuditQuery.java:104)
    at org.hibernate.envers.entities.mapper.relation.OneToOneNotOwningMapper.mapToEntityFromMap(OneToOneNotOwningMapper.java:74)
    at org.hibernate.envers.entities.mapper.MultiPropertyMapper.mapToEntityFromMap(MultiPropertyMapper.java:118)
    at org.hibernate.envers.entities.EntityInstantiator.createInstanceFromVersionsEntity(EntityInstantiator.java:93)
    at org.hibernate.envers.entities.mapper.relation.component.MiddleRelatedComponentMapper.mapToObjectFromFullMap(MiddleRelatedComponentMapper.java:44)
    at org.hibernate.envers.entities.mapper.relation.lazy.initializor.ListCollectionInitializor.addToCollection(ListCollectionInitializor.java:67)
    at org.hibernate.envers.entities.mapper.relation.lazy.initializor.ListCollectionInitializor.addToCollection(ListCollectionInitializor.java:39)
    at org.hibernate.envers.entities.mapper.relation.lazy.initializor.AbstractCollectionInitializor.initialize(AbstractCollectionInitializor.java:67)
    at org.hibernate.envers.entities.mapper.relation.lazy.proxy.CollectionProxy.checkInit(CollectionProxy.java:50)
    at org.hibernate.envers.entities.mapper.relation.lazy.proxy.CollectionProxy.size(CollectionProxy.java:55)
    at <MY CODE HERE, which checks list.size()>

Окончательное решение (На самом деле это скорее временный взлом)

boolean worked = false;
while (!worked) {
    try {
        if(list.size() == 1) {
            // do stuff 
        }
        worked = true;
    } catch (Exception e) {
        // TODO: exception must be accessed or the loop will be infinite
        e.getStackTrace();
    }
}

1 Ответ

4 голосов
/ 21 сентября 2011

Хорошо, что происходит, вы видите ленивую загрузку Hibernate в глубоком действии:)

В основном Hibernate загружает прокси-классы для вас, лениво связанных отношений, так что вместо Списка классов C вы получаете Список (на самом деле реализация PersistenceBag) автоматически сгенерированного прокси Hibernate для вашего класса C. Это способ hibernate отложить загрузку значений этой ассоциации, пока они не будут фактически доступны. Поэтому, когда вы обращаетесь к нему в отладчике eclipse (который в основном обращается к полям / метидам экземпляра через интроспекцию), вы видите триггеры sql hibernate для получения необходимых данных.

Хитрость в том, что в зависимости от того, КОГДА вы получаете доступ к ленивой коллекции, вы можете получить разные результаты. Если вы обращаетесь к нему с помощью отладчика eclipse, вы, скорее всего, все еще находитесь в сеансе Hibernate, который начал загружать эту вещь, поэтому все работает, как и ожидалось, sql запускается (лениво) при доступе к этой вещи и загрузке данных). Проблема в том, что если вы хотите получить доступ к тем же данным в вашем коде, но в тот момент, когда сессия уже закрыта, вы получите либо LazyInitializationException, либо null (последнее, если вы используете какую-то библиотеку для очистки, вставьте прокси hibenrate, например, как Галаад)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...