@Immutable à Hibernate

@Immutable à Hibernate

1. Vue d'ensemble

Dans cet article, nous allons parler de la manière dont nous pouvons créer une entité, une collection ou un attributImmutable dans Hibernate.

Par défaut, les champs sont modifiables, ce qui signifie que nous pouvons effectuer des opérations sur eux qui modifient leur état.

2. Maven

Pour que notre projet soit opérationnel, nous devons d'abord ajouter les dépendances nécessaires dans nospom.xml. Et comme nous travaillons avec Hibernate, nous allons ajouter lesdependency correspondants:


    org.hibernate
    hibernate-core
    5.2.8.Final

Et, comme nous travaillons avecHSQLDB, nous avons également besoin de:


    org.hsqldb
    hsqldb
    2.3.4

3. Annotation sur les entités

Tout d'abord, définissons une classe d'entité simple:

@Entity
@Immutable
@Table(name = "events_generated")
public class EventGeneratedId {

    @Id
    @Column(name = "event_generated_id")
    @GeneratedValue(generator = "increment")
    @GenericGenerator(name = "increment", strategy = "increment")
    private Long id;

    @Column(name = "name")
    private String name;
    @Column(name = "description")
    private String description;

    // standard setters and getters
}

Comme vous l'avez remarqué, nous avons déjà ajouté l'annotation@Immutable à notre entité, donc si nous essayons de sauvegarder unEvent:

@Test
public void addEvent() {
    Event event = new Event();
    event.setId(2L);
    event.setTitle("Public Event");
    session.save(event);
    session.getTransaction().commit();
    session.close();
}

Ensuite, nous devrions obtenir le résultat:

Hibernate: insert into events (title, event_id) values (?, ?)

La sortie doit être la même même si nous supprimons l’annotation, ce qui signifie qu’il n’ya aucun effet lorsque nous essayons d’ajouter une entité quelle que soit l’annotation.

Il est également important de noter que dans notre entitéEventGeneratedId, nous avons ajouté l'annotationGeneratedValue, mais cela ne fera une différence que lorsque nous créerons une entité. C'est parce qu'il spécifie la stratégie de génération de l'id - toute autre opération n'affectera pas le champId en raison de l'annotationImmutable.

3.1. Mettre à jour l'entité

Maintenant, nous n'avons eu aucun problème pour enregistrer une entité, essayons de la mettre à jour:

@Test
public void updateEvent() {
    Event event = (Event) session.createQuery(
      "FROM Event WHERE title='My Event'").list().get(0);
    event.setTitle("Public Event");
    session.saveOrUpdate(event);
    session.getTransaction().commit();
}

Hibernate ignorera simplement l'opérationupdate sans lever d'exception. Cependant, si nous supprimons l'annotation@Immutable, nous obtenons un résultat différent:

Hibernate: select ... from events where title='My Event'
Hibernate: update events set title=? where event_id=?

Ce que cela nous dit, c'est que notre objet est maintenant mutable (mutable est la valeur par défaut si nous n'incluons pas l'annotation) et permettra à la mise à jour de faire son travail.

3.2. Supprimer une entité

Lorsqu'il s'agit de supprimer une entité:

@Test
public void deleteEvent() {
    Event event = (Event) session.createQuery(
      "FROM Event WHERE title='My Event'").list().get(0);
    session.delete(event);
    session.getTransaction().commit();
}

Nous serons en mesure d'effectuer la suppression, qu'elle soit modifiable ou non:

Hibernate: select ... from events where title='My Event'
Hibernate: delete from events where event_id=?

4. Annotation sur les collections

Jusqu'à présent, nous avons vu ce que l'annotation fait aux entités, mais comme nous l'avons mentionné au début, elle peut également être appliquée aux collections.

Tout d'abord, ajoutons une collection à notre classeEvent:

@Immutable
public Set getGuestList() {
    return guestList;
}

Comme précédemment, nous avons ajouté l'annotation au préalable, donc si nous essayons d'ajouter un élément à notre collection:

org.hibernate.HibernateException:
  changed an immutable collection instance: [com.example.entities.Event.guestList#1]

Cette fois, nous obtenons une exception car, avec les collections, nous ne sommes pas autorisés à les ajouter ni à les supprimer.

4.1. Supprimer des collections

L'autre scénario où unCollection en étant immuable lèvera une exception, c'est chaque fois que nous essayons de supprimer et que nous avons défini l'annotation@Cascade.

Ainsi, chaque fois que@Immutable est présent et que nous essayons de supprimer:

@Test
public void deleteCascade() {
    Event event = (Event) session.createQuery(
      "FROM Event WHERE title='Public Event'").list().get(0);
    String guest = event.getGuestList().iterator().next();
    event.getGuestList().remove(guest);
    session.saveOrUpdate(event);
    session.getTransaction().commit();
}

Sortie:

org.hibernate.HibernateException:
  changed an immutable collection instance:
  [com.example.entities.Event.guestList#1]

5. Notes XML

Enfin, la configuration peut également être effectuée en utilisant XML via l'attributmutable=false:


    
        
            
        
        
    

Cependant, puisque nous avons essentiellement implémenté les exemples en utilisant la méthode des annotations, nous n'entrerons pas dans les détails en utilisant XML.

6. Conclusion

Dans cet article rapide, nous explorons l'annotation@Immutable utile d'Hibernate, et comment cela peut nous aider à définir une meilleure sémantique et des contraintes sur nos données.

Comme toujours, l'implémentation de tous ces exemples et extraits de code se trouve dansthe GitHub project. Ceci est un projet basé sur Maven, il devrait donc être facile à importer et à exécuter.