единица работы в "основном" приложении java - PullRequest
0 голосов
/ 08 января 2010

Я делаю это в каждом методе DAL:

 public static Product GetProductByPartNumber(String partNumber)
    {
         Session session = HibernateUtil.getSessionFactory().getCurrentSession();

         session.beginTransaction();


         Product product = (Product)session.createCriteria(Product.class)
                                    .add(Restrictions.eq("partNumber", partNumber))
                                    .uniqueResult();
         session.getTransaction().commit();



         return product;
    }

Это вызывает проблемы, выдает ошибки 'сеанс закрыт' из-за отложенной загрузки и т.д.

Как я могу получить getCurrentSession, чтобы не получать новый сеанс?

public class HibernateUtil {

    private static final SessionFactory sessionFactory = buildSessionFactory();

    private static SessionFactory buildSessionFactory() {
        try {
            // Create the SessionFactory from hibernate.cfg.xml
            Configuration configuration = new Configuration().configure();

            //configuration.addClass(hsspider.Model.AMCategory.class);

            return configuration.buildSessionFactory();
        }
        catch (Throwable ex) {
            // Make sure you log the exception, as it might be swallowed
            System.err.println("Initial SessionFactory creation failed." + ex);
            throw new ExceptionInInitializerError(ex);
        }
    }

    public static SessionFactory getSessionFactory() {
        return sessionFactory;
    }


}



 <!-- Enable Hibernate's automatic session context management -->
        <property name="current_session_context_class">thread</property>

Я предполагаю, что это проблема, что вызов getCurrentSession не получает текущий сеанс правильно?

Или же вызывает транзакции.commit (); убить сеанс? Должен ли я просто использовать флэш?

Ответы [ 2 ]

2 голосов
/ 08 января 2010

Вы смотрели на Transaction Javadoc, который я цитирую ниже?

Позволяет приложению определять единицы работы, сохраняя при этом абстракцию от реализации базовой транзакции (например, JTA, JDBC).

Транзакция связана с Session и обычно создается путем вызова Session.beginTransaction(). Один сеанс может охватывать несколько транзакций, поскольку понятие сеанса (диалог между приложением и хранилищем данных) имеет более грубую детализацию, чем понятие транзакции. Однако предполагается, что в любое время может быть не более одного незафиксированного Transaction, связанного с конкретным Session.

А, о Transaction#commit():

Сбросить связанный Session и завершить единицу работы (если только мы не находимся в FlushMode.NEVER. Этот метод выполнит базовую транзакцию, если и только если базовая транзакция была инициирована этим объектом.

Это должно ответить на ваш вопрос: commit() не прерывает сеанс (который может охватывать несколько транзакций, как мы видели).

Еще одна хорошая идея - установить точку останова и посмотреть на внутренние детали (вам может потребоваться сообщить вашей IDE, где найти источники Hibernate для этого).

Я также предлагаю проверить Сменное управление сессиями в Hibernate 3.1 и более поздние Сеансы и транзакции (особенно Разграничение транзакций с простым JDBC ).

0 голосов
/ 08 января 2010

Возможно, вы используете ThreadLocalSessionContex . Интересная часть этого Javadoc:

было решено иметь это значение по умолчанию на самом деле создать сеанс на сначала запрос, а затем очистить его после транзакции, связанной с этот сеанс зафиксирован / откат

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

Вы можете изменить поведение ThreadLocalSessionContext, поместив его в подкласс и повторно реализовав isAutoCloseEnabled () и другие методы. Вы должны были бы найти способ сигнализировать о закрытии сессии.

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