четверг, 31 марта 2011 г.

getCurrentSession() дубль 2


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

Согласно книге, стандартная архитектура приложения, использующего базу данных и какой-либо фреймворк для работы с ней (обычно это ORM - object-relational mapping система) состоит из 3 уровней:
- доменная модель - обьекты предметной области, которые и нужно сохранять в базе
- DAO - уровень, абстрагирующий нас от конкретной реализации операций с БД. Сюда входят интерфейсы, описывающие базовые операции с базой данных, например, сохранение обьекта, нахождение обьекта по условиям и т.д. В книге рекомендуется для каждой сущности доменной модели создавать свой DAO. Ну и конкретная реализация этих интерфейсов, в зависимости от выбраной ORM-системы, JDBC etc. При желании реализацию можно поменять, не меняя бизнес-логику (классы бизнес-логики зависят только от интерфейсов, описывающих общие методы доступа к БД, без ссылок на конкретную реализацию). А используя Spring это можно сделать, просто изменив файл конфигурации.
- Сервисный уровень - здесь реализуется бизнес-логика. Методы представляют собой unit of work с точки зрения предметной области. Ну там всякие снять деньги со счета-положить на другой счет в одной операции. Именно методы этого уровня рекомендуется делать транзакционными.

понедельник, 21 марта 2011 г.

Hibernate & автогенерация ID

Для того, чтобы автоматически сгенерировать ID для ентити, необходима запись вида:

@Id
@GeneratedValue(
strategy=GenerationType.TABLE)
public Long getId() {
   return id;
}

public void setId(Long id) {
   this.id = id;
}

понедельник, 14 марта 2011 г.

Транзакции

Оказывается, даже в самых известных API есть издержки проектирования, что очень сильно подрывает нашу, начинающих программеров, веру в Божественную Святую Непогрешимость людей, пишущих всю эту красоту. Возьмем к примеру интерфейс UserTransaction. Интерфейс представляет собой сущность - транзакцию. Мы ее можем начать (begin()), выполнить (commit()) или откатить (rollback() или setRollbackOnly()). И вот скажите мне, мои более опытные коллеги, для чего нужен второй метод setRollbackOnly()?
Аналогичным вопросом задался и один из завсегдатаев Салона Большого Лося:
http://www.coderanch.com/t/157891/java-EJB-SCBCD/certification/When-UserTransaction-setRollbackOnly-UserTransaction-rollback

Обратите внимание на ответ девушки:
"... you might know the transaction is going badly *before* you reach the place where the transaction actually ends. You might not want to end the tx at the moment you discover it won't work, for many reasons. Perhaps you want to keep only one place in your code where the transaction ends. Or... you might need the rest of the transactional code to run for other side-effects ..."

Переводя на русский, setRollbackOnly() используется тогда, когда в середине транзакции стало понятно, что что-то пошло не так и транзакцию надо откатить, но вы хотите, чтобы оставшийся код доработал до конца. Почему вы можете вдруг этого захотеть? У вас 2 варианта: либо вы поклонник модульного программирования и концепции один вход-один выход (вот ссылка http://high-info.ru/Modulnoe_programmirovanie.htm - правда его взломали, но картинки повставляли веселые и даже по теме), либо ваш код производит какие-то побочные эффекты, которые должны быть сохранены независимо от исхода транзации. В любом случае, все это очень сомнительно (http://en.wikipedia.org/wiki/Code_smell)

пятница, 11 марта 2011 г.

Разница между Hibernate openSession() и getCurrentSession()

Начала готовиться к собеседованию и делать тестовое приложение. Основной целью было вспомнить как собственно оно все пишется и настраивается в разных фреймворках. Для начала взяла Hibernate. Однако столкнулась с трудностью: в книге, по которой я изучала Hibernate (надеюсь, найду ее и вставлю ссылку) для получения сессии использовалась функция openSession(), а в текущей документации все примеры основаны на другой функции - getCurrentSession(). В SessionFactory есть обе эти функции, но в чем же разница? Поскольку мне предстоит собеседование решила исследовать вопрос.

Ссылки по теме:
Java docs
http://ajava.org/online/hibernate3api/org/hibernate/SessionFactory.html

А вот здесь человек очень хорошо все обьяснил, но по-английски:
http://www.jeevanchaaya.com/2009/04/11/getcurrentsession-or-opensession-a-sessionic-dilema/