Question

J'ai quelques questions sur l'interaction avec Hibernate:

  1. Dois-je utiliser openSession ou getCurrentSession (sans JTA, fil à la place)?
  2. Comment puis-je mélanger les opérations de session avec l'interface graphique Swing? Est-ce bien avoir quelque chose comme le code suivant dans une classe JavaBean?

    public void actionPerformed(ActionEvent event) {
        // session code
    }
    
  3. Can I méthodes d'ajouter à mes entités qui contient des requêtes HQL ou est-ce une mauvaise pratique? Par exemple:

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

Comment puis-je faire cela d'une manière meilleure et élégante?

UPDATE Une pratique largement utilisée est de faire une classe de service / dao pour assurer un fonctionnement CRUD de notre classe d'entités. Mais pourquoi est-ce bon? Pourquoi dois-je écrire une classe pour chaque mes entités pour le gérer? Où est l'avantage réel?

MISE À JOUR 2 La classe de service est un modèle de DAO? Qu'est-ce que ça veut dire? est un modèle de DAO, est-ce que l'on appelle une « couche de service »?

Était-ce utile?

La solution

Si vous voulez appuyer sur API Hibernate simple vous pouvez utiliser une couche de service parce que

  • Il est conduit cas d'utilisation
  • Délimiter les limites de transaction

Vous pouvez créer un AccountService, par exemple, comme

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

}

Vous devez généralement un dépôt lorsque vous effectuez une action dans votre couche de service. Vous pouvez penser référentiel en tant que fournisseur de données et de stockage . ici peut voir comment je mets en œuvre mon dépôt.

Si vous voulez un maintenable et lisible HQL requête , je vous conseille de externalisez vos requêtes HQL dans un fichier xml multline et extériorisée

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

GUI dans votre swing de l'événement, vous pouvez appeler votre couche de service comme

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

Et ce n'est pas une bonne idée d'utiliser la persistance des actions à l'intérieur de votre entité. Si vous devez effectuer la persistance des problèmes liés à l'intérieur de votre entité, je pense qu'il vaut mieux que vous passez votre dépôt en tant que paramètre à votre entité

public class Account {

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

}

Peut-être que vous voulez voir cette discussion

je vous conseille Jetez un oeil à Java Persistence avec le livre Hibernate, chapitre 9 (travail avec des objets). ATT : lire attentivement

UPDATE

  

Pourquoi est bon avoir une couche de service?

D'abord

  • Il est Cas d'utilisation conduit (Il dessine ce que votre application devrait faire)

Deuxièmement

  • déterminer les limites de transaction

Supposons ici va votre couche de service

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

}

Avis vous suffit de définir une limite de transaction au lieu de définir chacun à l'intérieur de chaque POJO. Et plus, ce qui se passe si votre règle d'affaires dans votre interface graphique swing besoin d'être utilisé à l'intérieur d'autres composants. Utiliserez-vous un Ctrl-c + Ctrl-v ???

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top