Pergunta

Tenho algumas perguntas sobre a interação com o Hibernate:

  1. Eu uso o OpenSession ou GetCurrentSession (sem JTA, Thread)?
  2. Como faço para misturar operações de sessão com a GUI do swing? É bom ter algo como o código a seguir em uma aula de Javabean?

    public void actionPerformed(ActionEvent event) {
        // session code
    }
    
  3. Posso adicionar métodos às minhas entidades que contêm consultas HQL ou isso é uma prática ruim? Por exemplo:

     // 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;
     }
    

Como posso fazer isso de uma maneira melhor e elegante?

ATUALIZARUma prática amplamente usada é fazer uma classe de serviço/DAO para alcançar a operação CRUD de nossa classe de entidades. Mas por que isso é bom? Por que tenho que escrever uma aula para cada uma das minhas entidades para gerenciá -la? Onde está a verdadeira vantagem?

Atualização 2A classe de serviço é um padrão DAO? O que isto significa?Exemplo de repositório de Arthur Ronald FD Garcia É um padrão DAO, é isso que é chamado de "camada de serviço"?

Foi útil?

Solução

Se você quiser confiar na API de hibernação simples você pode usar uma camada de serviço porque

  • É usar case orientado
  • Limites da transação delimit

Então você pode criar um serviço de conta, por exemplo, como

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();
    }

}

Você geralmente precisa de um repositório ao executar alguma ação dentro da camada de serviço. Você pode pensar em repositório Como provedor de dados e armazenamento. Aqui Você pode ver como eu implemento meu repositório.

Se você quiser uma consulta HQL sustentável e legível, Eu aconselho que você externalize suas consultas HQL em um arquivo XML multineado e externalizado

<?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>

Então, dentro do seu evento GUI Swing, você pode chamar sua camada de serviço como

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));
}

E não é uma boa ideia usar ações de persistência dentro de sua entidade. Se você precisar realizar problemas relacionados à persistência dentro de sua entidade, acho que é melhor você passar seu repositório como parâmetro para sua entidade

public class Account {

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

}

Talvez você queira ver isto Fio

Conselho você dar uma olhada na persistência de Java com o livro de hibernados, capítulo 9 (trabalhando com objetos). Att: Leia cuidadosamente

ATUALIZAR

Por que é bom ter uma camada de serviço?

Em primeiro lugar

  • É usado no caso (ele desenha o que seu aplicativo deve fazer)

Segundo de todos

  • Ele delimita os limites da transação

Suponha que aqui seja sua camada de serviço

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();
    }

}

Observe que você apenas define um limite de transação em vez de definir cada um dentro de cada pojo. E mais, o que acontece se sua regra de negócios dentro de sua GUI swing precisa ser usada dentro de outro componente. Você vai usar um Ctrl-C + Ctrl-V ???

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top