Exemple mutable Hibernate (classe et collection)

Exemple de mise en veille prolongée (classe et collection)

En veille prolongée, «mutable» est défini par défaut sur «true» dans la classe et sa collection associée, cela signifie que la classe ou la collection est autorisée à ajouter, mettre à jour et supprimer. D'un autre côté, si le mutable est changé en false, il a une signification différente dans la classe et sa collection associée. Prenons quelques exemples pour en savoir plus.

Exemple d'hibernation un-à-plusieurs

Je prendrai cesone-to-many example pour la démonstration mutable. Dans ce fichier de mappage, un Stock appartient à de nombreux StockDailyRecord.

...

    
        
            
                
            
            
        
    
...

Comment déclarer mutable?

Le «mutable» est pris en charge à la fois dans le fichier de mappage XML et dans les annotations.

1. Fichier de mappage XML

Dans le fichier de mappage, le mot-clé ‘mutable’ est utilisé pour implémenter la fonction mutable.

...

    
        
            
                
            
            
        
    
...

2. Annotation

Dans l'annotation, le mot clé est changé en @Immutable (mutable = ’false’).

...
@Entity
@Immutable
@Table(name = "stock", catalog = "example")
public class Stock implements java.io.Serializable {
...
        @OneToMany(fetch = FetchType.LAZY, mappedBy = "stock")
    @Immutable
    public Set getStockDailyRecords() {
        return this.stockDailyRecords;
    }
...

Mutable en classe

Si mutable = "false" ou @Immutable est déclaré dans l'élément de classe, cela signifie lesupdates to this class will be ignored, but no exception is thrown, only the add and delete operation are allow.

1. Insert de test

Stock stock = new Stock();
stock.setStockCode("7277");
stock.setStockName("DIALOG");
session.save(stock);

si mutable = «true» (par défaut) ou aucun @Immutable n'est déclaré dans la classe.
Output

Hibernate:
    insert into example.stock (STOCK_CODE, STOCK_NAME)
    values (?, ?)

si mutable = «false» ou @Immutable est déclaré dans la classe.
Output

Hibernate:
    insert into example.stock (STOCK_CODE, STOCK_NAME)
    values (?, ?)

Mutable in class n’a aucun effet sur l’opération «insérer».

2. Mise à jour du test

Stock stock = (Stock)session.createQuery(
      " from Stock where stockCode = '7277'").list().get(0);
stock.setStockName("DIALOG123");
session.saveOrUpdate(stock);

si mutable = "true" ou aucun @Immutable n'est déclaré dans la classe.
Output

Hibernate:
    select ...from example.stock stock0_
    where stock0_.STOCK_CODE='7277'

Hibernate:
    update example.stock
    set STOCK_CODE=?,STOCK_NAME=?
    where STOCK_ID=?

si mutable = «false» ou @Immutable est déclaré dans la classe.
Output

Hibernate:
    select ...from example.stock stock0_
    where stock0_.STOCK_CODE='7277'

Mutable dans la classe ne permet pas à l'application de le mettre à jour, l'opération de «mise à jour» sera ignorée et aucune exception n'est levée

3. Test de suppression

Stock stock = (Stock)session.createQuery(
      " from Stock where stockCode = '7277'").list().get(0);
session.delete(stock);

si mutable = «true» (par défaut) ou aucun @Immutable n'est déclaré dans la classe.
Output

Hibernate:
    delete from example.stock
    where STOCK_ID=?

si mutable = «false» ou @Immutable est déclaré dans la classe.
Output

Hibernate:
    delete from example.stock
    where STOCK_ID=?

Mutable en classe n’a aucun effet sur l’opération de «suppression».

Mutable en collection

Si mutable = «false» ou @Immutable est déclaré dans la collection, cela signifie lesadd and delete-orphan are not allow in this collection, with exception throw, only update and ‘cascade delete all’ are allow.

1. Insert de test

Supposons que l'insertion en cascade est activée.

Stock stock = (Stock)session.createQuery(
      " from Stock where stockCode = '7277'").list().get(0);
StockDailyRecord sdr = new StockDailyRecord();
sdr.setDate(new Date());
sdr.setStock(stock);
stock.getStockDailyRecords().add(sdr);
session.save(stock);

si mutable = «true» (par défaut) ou aucun @Immutable n'est déclaré dans la collection.
Output

Hibernate:
    insert into example.stock_daily_record
    (STOCK_ID, PRICE_OPEN, PRICE_CLOSE, PRICE_CHANGE, VOLUME, DATE)
    values (?, ?, ?, ?, ?, ?)

si mutable = «false» ou @Immutable est déclaré dans la collection.
Output

Exception in thread "main" org.hibernate.HibernateException:
changed an immutable collection instance:
[com.example.common.Stock.stockDailyRecords#111]

Mutable dans la collection n’autorise pas l’opération «ajouter», une exception sera levée.

2. Mise à jour du test

Supposons que la mise à jour en cascade soit activée.

Stock stock = (Stock)session.createQuery(
      " from Stock where stockCode = '7277'").list().get(0);
StockDailyRecord sdr = stock.getStockDailyRecords().iterator().next();
sdr.setPriceChange(new Float(1.30));
session.saveOrUpdate(stock);

si mutable = «true» (par défaut) ou aucun @Immutable n'est déclaré dans la collection.
Output

Hibernate:
    update example.stock_daily_record
    set PRICE_CHANGE=?, ...
    where DAILY_RECORD_ID=?

si mutable = «false» ou @Immutable est déclaré dans la collection.
Output

Hibernate:
    update example.stock_daily_record
    set PRICE_CHANGE=?, ...
    where DAILY_RECORD_ID=?

Mutable dans la collection n’a aucun effet sur l’opération de «mise à jour».

3. Test de suppression-orphelin

Supposons que lecascade delete-orphan est activé.

Stock stock = (Stock)session.createQuery(
      " from Stock where stockCode = '7277'").list().get(0);
StockDailyRecord sdr = stock.getStockDailyRecords().iterator().next();
stock.getStockDailyRecords().remove(sdr);
session.saveOrUpdate(stock);

si mutable = «true» (par défaut) ou aucun @Immutable n'est déclaré dans la collection.
Output

Hibernate:
    delete from example.stock_daily_record
    where DAILY_RECORD_ID=?

si mutable = «false» ou @Immutable est déclaré dans la collection.
Output

Exception in thread "main" org.hibernate.HibernateException:
changed an immutable collection instance:
[com.example.common.Stock.stockDailyRecords#111]

Mutable dans la collection n’autorise pas l’opération ‘delete-orphan’, une exception sera levée.

4. Test de suppression

Supposons que la suppression en cascade est activée.

Stock stock = (Stock)session.createQuery(
      " from Stock where stockCode = '7277'").list().get(0);
session.saveOrUpdate(stock);

si mutable = «true» (par défaut) ou aucun @Immutable n'est déclaré dans la collection.
Output

Hibernate:
    delete from example.stock_daily_record
    where DAILY_RECORD_ID=?

Hibernate:
    delete from example.stock
    where STOCK_ID=?

si mutable = «false» ou @Immutable est déclaré dans la collection.
Output

Hibernate:
    delete from example.stock_daily_record
    where DAILY_RECORD_ID=?

Hibernate:
    delete from example.stock
    where STOCK_ID=?

Mutable dans la collection n’a aucun effet sur l’opération de «suppression», si le parent est supprimé, tout son enfant sera également supprimé, même s'il est modifiable.

Pourquoi mutable?

Mutable peut éviter de nombreuses opérations de base de données involontaires, comme ajouter, mettre à jour ou supprimer certains enregistrements qui ne devraient pas l'être. De plus, selon la documentation Hibernate, le do mutable a quelques optimisations de performances mineures, il est toujours recommandé d'analyser votre relation de mappage et d'implémenter le mutable selon les besoins.

Sommaire

1. mutable = "false" ou @Immutable est déclaré en classe

cela signifie que les mises à jour de cette classe seront ignorées, mais aucune exception n'est levée, seules les opérations d'ajout et de suppression sont autorisées.

En classe avec mutable = "false" - insert = allow, delete = allow, update = not allow

2. mutable = "false" ou @Immutable est déclaré dans la collection

cela signifie que les ajouts et les suppressions d'orphelins ne sont pas autorisés dans cette collection, à l'exception du lancer, seule la mise à jour est autorisée. Cependant, si la suppression en cascade est activée, lorsque le parent est supprimé, tout son enfant sera également supprimé, même s'il est modifiable.

Dans la collection avec mutable = "false" - insert = not allow, delete-orphan = not allow, delete = allow, update = allow

Complètement immuable?

Une classe peut-elle complètement immuable à des actions? Oui, mettez un mutable = "faux" à toute sa relation (insert = pas autorisé, delete-orphan = pas autorisé), et un mutable = "faux" à la classe que vous voulez immuable (update = pas autoriser). Maintenant, vous avez une classe complètement immuable, cependant, si l'option de suppression en cascade est activée, lorsque le parent de votre classe immuable est supprimé, votre classe immuable sera également supprimée.