Как я могу хорошо смешивать Hibernate и Swing

У меня есть несколько вопросов по взаимодействию с Hibernate:

  1. Использую ли я openSession или getCurrentSession (без jta, вместо этого thread)?
  2. Как смешивать сеансовые операции с графическим интерфейсом Swing? Хорошо ли иметь что-то вроде следующего кода в классе JavaBean?

    public void actionPerformed(ActionEvent event) {
        // session code
    }
    
  3. Могу ли я добавлять методы к своим сущностям, которые содержат запросы HQL, или это плохая практика? Например:

     // This method is in an entity MyOtherEntity.java class
     public int getDuration(){
        Session session = HibernateUtil.getSessionFactory().getCurrentSession();
        session.beginTransaction();
        int sum = (Integer) session.createQuery("select sum(e.duration) as duration from MyEntity as e where e.myOtherEntity.id=:id group by e.name").
            .setLong("id", getId());
            .uniqueResult();
        return sum;
     }
    

Как я могу сделать это лучше и элегантнее?

ОБНОВЛЕНИЕ Широко распространенной практикой является создание класса службы/дао для выполнения CRUD-операции нашего класса сущностей. Но почему это хорошо? Почему я должен писать класс для каждой моей сущности, чтобы управлять ею? Где настоящее преимущество?

ОБНОВЛЕНИЕ 2. Класс обслуживания — это шаблон DAO? Что это значит? Пример репозитория Артура Рональда FD Garcia — это шаблон DAO, это то, что называется «сервисным уровнем»?


person blow    schedule 17.06.2010    source источник
comment
Потому что мой вопрос заключается в том, как правильно смешивать спящий режим и качание.   -  person blow    schedule 19.06.2010
comment
хахаха... лол. хороший вопрос задан :D @blow   -  person gumuruh    schedule 24.11.2011


Ответы (1)


Если вы хотите полагаться на простой Hibernate API, вы можете использовать сервисный уровень, потому что

  • Это зависит от варианта использования
  • Разграничить границы транзакции

Таким образом, вы можете создать AccountService, например, например

public static path.to.HibernateUtil.getSessionFactory;

public class AccountService {

    public void withdraw(Integer accountNumber, BigDecimal amount) throws Exception {
        /**
          * Here you set up Transaction boundaries
          */
        getSessionFactory().getCurrentSession().beginTransaction();

        // Some actions goes here

        getSessionFactory().getCurrentSession().getTransaction().commit();
    }

}

Обычно вам нужен репозиторий при выполнении каких-либо действий внутри уровня службы. Вы можете думать о репозитории как о поставщике и хранилище данных. Здесь вы можно увидеть, как я реализую свой репозиторий.

Если вам нужен удобный и читаемый HQL-запрос, я советую вам экспортировать ваши HQL-запросы в многострочный и внешний xml-файл.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <query name="GIFT_CARDS_WITH_BUYER">
        <![CDATA[
            from 
                GiftCard c
            left join fetch 
                c.buyer
            where
                c.recipientNotificationRequested = 1
       ]]>
    </query>
    <query name="GIFT_CARDS_WITHOUT_NO_RELATIONSHIP">
        <![CDATA[
            from 
                GiftCard
        ]]>
    </query>
</hibernate-mapping>

Таким образом, внутри вашего события Swing GUI вы можете вызвать свой сервисный уровень, например

public void actionPerformed(ActionEvent event) {
    // Some related Swing GUI actions goes here (retrieve User input, validate data and so on...)

    accountService.withdraw(accountNumber, new BigDecimal(amount));
}

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

public class Account {

   public void doSomething(AccountRepository repository) {
       // code goes here
   }

}

Возможно, вы хотите увидеть эта тема

Я советую вам взглянуть на книгу Java Persistence with Hibernate, глава 9 (Работа с объектами). ВНИМАНИЕ: прочитайте внимательно

ОБНОВЛЕНИЕ

Почему хорошо иметь уровень обслуживания?

Прежде всего

  • Он основан на прецедентах (он рисует, что должно делать ваше приложение)

На втором месте

  • Он разграничивает границы транзакций

Предположим, здесь идет ваш сервисный уровень

public class MyService {

    public void doSomething() {
        getSessionFactory().beginTransaction();

        // A POJO doing some operation

        // Other POJO doing other operation

        // Another POJO doing another operation

        getSessionFactory().getTransaction().commit();
    }

}

Обратите внимание, что вы просто определяете одну границу транзакции вместо того, чтобы определять каждую внутри каждого POJO. И еще, что произойдет, если ваше бизнес-правило внутри вашего графического интерфейса Swing нужно использовать внутри другого компонента. Будете ли вы использовать Ctrl-c + Ctrl-v ???

person Arthur Ronald    schedule 17.06.2010
comment
Привет! спасибо, ваш ответ дал мне еще один вопрос .. Почему хорошо иметь сервисный уровень? Я обновляю свой пост. - person blow; 19.06.2010
comment
Хорошо, теперь я думаю, чтобы понять .. я надеюсь :) Еще раз спасибо! - person blow; 19.06.2010
comment
@blow См. stackoverflow.com/questions/2597219/ Чтобы получить хорошее представление о том, где я использую Сервис (используйте прецедент и границу транзакции) и репозиторий (для извлечения сущности). Имейте в виду, что вам не нужен каждый репозиторий для каждой имеющейся у вас сущности. При необходимости вы просто пишете репозиторий. - person Arthur Ronald; 19.06.2010