Открыть сессию в виде шаблона

Ответ Галика имеет ряд проблем безопасности. Вот как я сделал бы это в Modern C ++:

#include 
#include 
#include 

void old_func(char** carray, std::size_t size)
{
    for(std::size_t i(0); i < size; ++i)
        std::cout << carray[i] << '\n';
}

void other_old_func(const char** carray, std::size_t size)
{
    for(std::size_t i(0); i < size; ++i)
        std::cout << carray[i] << '\n';
}

int main()
{
    {
        std::cout << "modifiable version\n";
        std::vector strings{"one", "two", "three"};
        std::vector cstrings{};

        for(auto& string : strings)
            cstrings.push_back(&string.front());

        old_func(cstrings.data(), cstrings.size());

        std::cout << "\n\n";
    }
    {
        std::cout << "non-modifiable version\n";
        std::vector strings{"four", "five", "six"};
        std::vector cstrings{};

        for(const auto& string : strings)
            cstrings.push_back(string.c_str());

        other_old_func(cstrings.data(), cstrings.size());
        std::cout << std::endl;
    }
}

Нет беспорядочного управления памятью или неприятного const_cast s.

Live on Coliru.

Выходы:

modifiable version
one
two
three


non-modifiable version
four
five
six

13
задан Matt Ball 21 July 2010 в 05:41
поделиться

6 ответов

Я успешно решил всю мою ленивую инициализацию проблемы с Open Session In View -pattern (т.е. реализация Spring). Технологии, которые я использовал, были точно такими же, как и вы.

Использование этого шаблона позволяет мне полностью отображать отношения сущностей и не беспокоиться о выборке дочерних сущностей в дао. В основном. В 90% случаев шаблон решает ленивую инициализацию представления. В некоторых случаях вам придется инициализировать отношения «вручную». Эти случаи были редкими и в моем случае всегда включали очень сложные сопоставления.

При использовании шаблона Open Entity Manager In View важно правильно определить отношения сущностей и особенно настройки распространения и транзакций. Если они не настроены должным образом, возникнут ошибки, связанные с закрытыми сеансами, когда некоторая сущность лениво инициализируется в представлении и не удается из-за того, что сеанс уже был закрыт.

Я определенно выбрал бы вариант 1. Вариант 2 мог бы иногда может понадобиться, но я не вижу абсолютно никаких причин использовать вариант 3. Вариант 4 тоже не годится. Жадная выборка всего убивает производительность любого представления, которому необходимо перечислить всего несколько свойств некоторых родительских сущностей (в данном случае заказы).

N + 1 Selects

Во время разработки будет N + 1 выборок в результате инициализации некоторых отношений в представлении. Но это не повод отказываться от шаблона. Просто устраняйте эти проблемы по мере их возникновения и перед отправкой кода в производство. Эти проблемы можно исправить с помощью шаблона OEMIV так же легко, как и с любым другим шаблоном: добавить соответствующие методы dao или службы, исправить контроллер для вызова другого метода поиска, возможно, добавить представление в базу данных и т. Д.

10
ответ дан 1 December 2019 в 20:29
поделиться

Открытый сеанс в представлении имеет некоторые проблемы .

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

Другой пример, чтение данных по запросу может привести к множеству "N +1 выберите "проблемы , которые убивают вашу производительность.


Во многих проектах используется следующий путь:

  1. Ведение транзакций на бизнес-уровне ; загрузите в этот момент все, что вам нужно.
  2. Уровень представления подвержен риску LazyExceptions: каждое из них считается ошибкой программирования, обнаруженной во время тестов, и исправлено путем загрузки дополнительных данных на бизнес-уровень (у вас есть возможность сделать это эффективно, избегая проблем "N + 1 select").

Чтобы избежать создания дополнительных классов для DTO, вы можете загружают данные внутри самих объектов сущностей . В этом весь смысл подхода POJO (используется современными уровнями доступа к данным и даже технологиями интеграции, такими как Spring).

15
ответ дан 1 December 2019 в 20:29
поделиться

Однако есть некоторые преимущества подхода DTO. Вы должны заранее подумать, какая информация вам нужна. В некоторых случаях это предотвратит создание n + 1 операторов выбора. Это также помогает увидеть, где использовать активную выборку и / или оптимизированные представления.

1
ответ дан 1 December 2019 в 20:29
поделиться

Составляют ли строки заказа и заказа большой объем данных? Участвуют ли они в онлайн-процессах, где требуется реагирование в режиме реального времени? Если да, то вы можете не использовать активную выборку - это сильно влияет на производительность. Если количество данных невелико, нет проблем с активной выборкой.

Что касается использования DTO, это может быть жизнеспособной реализацией. Если ваш бизнес-уровень используется внутри вашего собственного приложения (т.е. небольшого веб-приложения и его бизнес-логики), вероятно, лучше всего будет использовать ваши собственные сущности в вашем представлении с открытым сеансом в шаблоне представления, поскольку это проще.

Если ваши объекты используются многими приложениями (т. Е. Серверным приложением, предоставляющим услугу в вашей корпорации), было бы интересно использовать DTO, поскольку вы не открыли бы свою модель своим клиентам. Его раскрытие может означать, что вам будет сложнее рефакторинг вашей модели, поскольку это может означать разрыв контрактов с вашими клиентами. DTO упростит это, поскольку у вас есть еще один уровень абстракция. Это может показаться немного странным, поскольку EJB3 теоретически устранит необходимость в DTO.

0
ответ дан 1 December 2019 в 20:29
поделиться

Я также выброшу свой вес за спиной с открытым сеансом, имея в той же лодке раньше.

Я работаю с полосами без весны, и создал ручной фильтр, прежде чем это имеет тенденцию работать хорошо. Логика транзакции кодирования на бэкэнде станет грязным действительно быстрым, как вы упомянули. С нетерпением ждет, что все становится ужасно, поскольку вы набрали все больше и больше объектов друг другу.

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

С стристами вы можете сказать такие вещи, как / AppContExtroot / Действия / View / 3 , и он будет автоматически гидратировать объект JPA на эффекте ActionBean с идентификатором 3, прежде чем событие выполняется.

Stripersist находится в пакете пакета на полоску на SourceForge . Теперь я использую это для всех новых проектов, так как он чистый и легко поддерживает несколько данных источников данных при необходимости.

1
ответ дан 1 December 2019 в 20:29
поделиться

Я успешно использовал шаблон Open-Session-in-View в своем проекте. Однако я недавно прочитал в «Spring In Practice» интересную потенциальную проблему с неповторяющимся чтением, если вы управляете своими транзакциями на более низком уровне, сохраняя при этом сеанс Hibernate открытым на уровне представления.

Мы управляли большинством наших транзакций на уровне сервиса, но оставляли сессию гибернации открытой на уровне представления. Это означало, что ленивое чтение в представлении приводило к отдельным транзакциям чтения.

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

Поскольку наша система так и не была запущена в производство, я не уверен, были ли с ней какие-либо реальные проблемы, но подозреваю, что у представления была возможность лениво загрузить объект, который был удален кем-то другим.

3
ответ дан 1 December 2019 в 20:29
поделиться
Другие вопросы по тегам:

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