Как отключить объект спящего режима

Как я могу проксировать объект спящего режима, чтобы полиморфизм поддерживался?

Рассмотрим следующий пример. Классы A и B представляют собой два объекта спящего режима. B имеет два подтипа C и D.

List<A> resultSet = executeSomeHibernateQuery();
for(A nextA : resultSet) {
    for(B nextB : nextA.getBAssociations() {
        if(nextB instanceof C) {
            // do something for C
        } else if (nextB instanceof D) {
            // do something for D
        }
    }
}

Этот код не может выполнять блок C или D, так как коллекция B была загружена лениво, а все экземпляры B - это прокси-серверы Hibernate. Мне нужен способ unproxy каждого экземпляра.

Примечание. Я понимаю, что запрос может быть оптимизирован для того, чтобы с нетерпением получить все B. Я ищу альтернативу.

+6
источник поделиться
2 ответа

Здесь наше решение, добавленное к нашему упорству utils:

public T unproxy(T proxied)
{
    T entity = proxied;
    if (entity instanceof HibernateProxy) {
        Hibernate.initialize(entity);
        entity = (T) ((HibernateProxy) entity)
                  .getHibernateLazyInitializer()
                  .getImplementation();
    }
    return entity;
}
+18
источник

Решение с использованием HibernateProxy и метода getImplementationMeterod является правильным.

Однако я предполагаю, что вы работаете в этом, потому что ваша коллекция определяется как интерфейс, а спящий режим представляет прокси-серверы интерфейса.

Это приводит к вопросу о дизайне, почему "if" с "instanceof" вместо использования метода интерфейса делает то, что вам нужно.

Итак, ваш цикл будет выглядеть следующим образом:

for(B nextB : nextA.getBAssociations() {
    nextB.doSomething();
}

Таким образом, hibernate делегирует вызов "doSomething()" на фактический объект реализации, и вы никогда не узнаете разницу.

+2
источник

Связанные вопросы


Похожие вопросы

Посмотрите другие вопросы по меткам или Задайте вопрос