Hamed Cédric SYLLA

🚀 Spring Boot – Passe à la vitesse supérieure : Gère tes migrations SQL comme un pro avec Flyway

🪧 Introduction

Qui n’a jamais utilisé spring.jpa.hibernate.ddl-auto=update pour faire évoluer le schéma de sa base de données dans un projet Spring Boot ?
C’est simple, rapide, mais… peut être dangereux.

Beaucoup de développeurs Java/Spring ne savent pas qu’il existe des outils pros comme Flyway pour gérer les évolutions de la base de données. Ces outils permettent de versionner chaque modification et d’assurer la stabilité du projet, même en équipe.

Dans cet article, je t’explique pourquoi il faut sortir de la « magie » Hibernate, comment fonctionne Flyway, et comment l’adopter simplement dans tes projets.

Cet article va t’expliquer :

  • Les limites et les risques de ddl-auto
  • Les différentes valeurs de la propriété Spring Boot
  • Les avantages de Flyway, comparé à la génération automatique
  • Un exemple concret d’intégration et de migration
  • Les bonnes pratiques à adopter (et les pièges à éviter)

1. ⚠️ ddl-auto=update : la fausse bonne idée

Dans la majorité des tutos, on voit souvent ceci :

Mais sais-tu vraiment ce que cela fait ?
Petit tour d’horizon des valeurs possibles :

ValeurEffetExemple d’utilisation
noneAucune action. Ne touche pas à la base.En production
createCrée tout le schéma à chaque démarrage (écrase tout).Pour les tests jetables, jamais en prod
create-dropCrée au démarrage, supprime à l’arrêtTests locaux
updateSynchronise les entités et le schéma (en théorie…)Développement rapide, mais peut facilement présenter un DANGER
validateVérifie la conformité, ne modifie rienPour contrôler sans toucher à la base

Pourquoi “update” pose problème ?

  • Ajout de nouveaux champs, mais gère mal les suppressions, renommages, types modifiés
  • Impossible de prévoir ce qui va vraiment se passer (surtout sur une base déjà peuplée et si on travaille en équipe)
  • Aucun historique ni possibilité de rollback
  • Collaboration compliquée : si deux devs font évoluer le schéma, gare aux surprises !
  • En prod, tu risques de perdre des données ou de casser ton application sans retour arrière

⚠️ ddl-auto=update est pratique pour un prototype ou un POC, mais à bannir dès que le projet devient sérieux !

2. 🚦Pourquoi Flyway ? Le contrôle, tout simplement

Flyway, c’est un outil de migration de base de données simple et puissant qui t’aide à :

  • Versionner chaque modification du schéma (fini les « je ne sais plus ce qui a été modifié »)
  • Écrire des scripts SQL explicites, versionnés, stockés dans ton repo Git
  • Appliquer les modifications dans l’ordre et traçable
  • Revenir en arrière si besoin (dans la limite des scripts écrits)
  • Travailler en équipe sans se marcher sur les pieds

Le principe ?

Chaque migration est un fichier SQL versionné (V1__init.sql, V2__add_user_table.sql, etc.).
Flyway garde en base un historique de ce qui a déjà été appliqué. À chaque démarrage, il applique seulement les nouveaux scripts.

3. 👨‍💻 Intégrer Flyway dans un projet Spring Boot

Étape 1 – Ajouter la dépendance Flyway

Avec Maven :

Étape 2 – Le dossier de migration

Par défaut, les scripts de migration doivent être placés dans le dossier src/main/resources/db/migration.
Ce répertoire est utilisé automatiquement par Flyway, mais tu peux le modifier à ta convenance via la propriété spring.flyway.locations dans ton application.properties.

Étape 3 – Écrire les scripts SQL

  • Les scripts sont nommés ainsi : V1__init.sql, V2__add_column.sql, etc.
  • Ils sont exécutés dans l’ordre des versions (V1, V2, etc. indique l’ordre d’exécution)

Exemple

Script de création de la table users
Script de modification de la table users afin d’ajouter le champ email

Étape 4 – Configurer Flyway (optionnel, Spring le fait pour toi)

Tu peux, si besoin, ajuster le comportement de Flyway dans le fichier application.properties.
Par défaut, la configuration fonctionne sans rien changer, mais sache que presque tout est personnalisable selon tes besoins : chemin des migrations, nom du schéma, activation/désactivation, etc.

Au démarrage, Flyway vérifie la base, voit quelles migrations manquent, et les applique.

4. 🛡️ Bonnes pratiques et conseils

  • Toujours désactiver ddl-auto en production (none ou validate)
  • Versionne tes scripts SQL
  • Ne mélange pas la génération automatique et Flyway : une seule source de vérité
  • Teste chaque migration sur une base locale AVANT de déployer en prod
  • Nomme tes fichiers de manière explicite : facile à relire, à comprendre et à auditer (cela facilite aussi le travail en équipe)

5. ⚡ Avantages concrets de Flyway

Lisibilité : chaque migration est claire, traçable, et explicite
Collaboration : chacun ajoute ses migrations, aucun risque de conflit caché
Facilité de rollback (au moins sur les migrations simples, en réécrivant le script inverse)
Aucune magie : c’est toi qui pilote !
Adapté à toutes les bases SQL : PostgreSQL, MySQL, MariaDB, etc.

6. ❗️Limites à connaître

✖️ Pas de rollback automatique : Flyway ne revient pas en arrière tout seul. Si tu veux annuler une migration, tu dois écrire le script inverse manuellement.
✖️ Scripts à maintenir : plus il y a de migrations, plus il faut organiser et documenter ses fichiers pour garder la cohérence.
✖️ Migration destructive à manier avec précaution : les suppressions ou modifications de colonnes doivent être bien réfléchies pour ne pas perdre de données.
✖️ Pas adapté au NoSQL : Flyway gère uniquement les bases SQL.
✖️ Prise en main nécessaire : demande un petit effort de discipline par rapport à ddl-auto, surtout au début, le temps de prendre le pli.

Au final :
Même si Flyway impose un peu plus de rigueur et d’organisation qu’un simple ddl-auto=update, c’est ce qui en fait un outil pro et fiable ! Les limites sont largement compensées par la sécurité et la maîtrise des évolutions de ta base.

7. ❌ Ce qu’il ne faut PAS faire

  • Laisser ddl-auto=update tourner en parallèle de Flyway
  • Modifier la base « à la main » sans migration (oublie direct ce qui a été fait)
  • Faire des scripts trop gros, ou peu explicites (“V15__global_changes.sql”)
  • Oublier de tester sur une copie de la prod (avant d’exécuter en prod)

🧭 Conclusion

Avec Flyway, tu passes d’une gestion hasardeuse à une maîtrise totale de l’évolution de ta base de données.
Fini les surprises et les conflits liés à ddl-auto=update : chaque modification est tracée, testée, et versionnée.
Tu gagnes en transparence, en sécurité, et tu facilites le travail en équipe.

La base d’un projet solide commence par des migrations maîtrisées !

📚 Sources & lectures recommandées

Spring Boot – Écoutez vos entités sans faire crier votre code : SQL vs MongoDB

Introduction

Saviez-vous que vous pouvez déclencher des actions automatiquement dans Spring Boot à chaque fois qu’une entité est créée, modifiée ou supprimée ?

Grâce aux EntityListeners (JPA) ou aux EventListeners MongoDB, Spring permet de réagir à la vie de vos entités, sans avoir à le coder dans vos services.

Mais cette magie peut rapidement devenir dangereuse si mal utilisée : logique invisible, difficultés de test, couplage fort, etc.

Cet article explore :

  • la différence entre les deux types de listeners
  • les méthodes à override
  • les avantages réels, mais surtout les inconvénients
  • comment les utiliser sans compromettre la lisibilité et la maintenabilité (Clean Code)

1. Pourquoi vouloir « écouter » les entités ?

Cas d’usage typiques :

  • Mettre à jour automatiquement des champs
  • Logger les opérations
  • Nettoyer les champs (email en lowercase, suppression d’espaces)
  • Déclencher des événements métiers (notifications, alertes…)

Centraliser du comportement transversal, sans l’éparpiller dans tous vos services.

2. EntityListeners (JPA – SQL)

2.1 Activation

L’activation se fait avec l’annotation @EntityListeners

2.2 Exemple d’implémentation

Toutes les méthodes prennent un seul paramètre : l’entité concernée (de type Object ou typé comme sur l’exemple si vous le souhaitez).

3. MongoDB : AbstractMongoEventListener (Spring Data Mongo)

3.1 Activation

3.2 Exemple d’implémentation

Les méthodes reçoivent un unique événement typé, ex. BeforeSaveEvent<User>.
Utilisez event.getSource() pour l’objet Java, event.getDocument() pour le BSON, et event.getCollectionName() si besoin.

4. Comparaison SQL vs Mongo

CritèreEntityListener (JPA)Mongo Event Listener
StandardJPA / Hibernate (Java EE)Spécifique Spring Data Mongo
Accès aux donnéesObjet Java uniquementObjet Java + Document BSON
Type de méthodesAnnotations (@PrePersist,…)Méthodes à override
Contexte (user/session)DifficileDifficile
Complexité des scénariosMoyennePlus riche grâce aux événements typés
Lisibilité / MaintenanceRisque élevé si abuséRisque élevé si abusé

5. Clean Code : ce qu’il faut absolument éviter

Mauvaises pratiques

  • Mettre de la logique métier lourde (ex : appel à une API, envoi de mail, billing…)
  • Modifier d’autres entités ou collections dans le listener sans contrôle transactionnel
  • Utiliser des listeners comme une “solution magique” pour éviter les services

Bonnes pratiques

  • Garder les listeners simples et prévisibles
  • Ne faire que des tâches techniques (audit, nettoyage, timestamps…)
  • Si besoin de logique métier : publier un événement Spring (ApplicationEventPublisher) et le traiter ailleurs
  • Bien documenter chaque listener
  • Tester isolément chaque listener

6. Tester les Listeners

  • Tester les listeners de façon unitaire (Mockito sur les événements)
  • Attention : certains listeners s’exécutent aussi dans les tests d’intégration
  • Prévoir une désactivation conditionnelle (via @Profile("!test"), par exemple)

7. Avantages / Inconvénients

Avantages

  • Centralise des comportements communs
  • Évite de dupliquer des blocs de code (ex : timestamps)
  • Simplifie les entités en surface

Inconvénients

  • Logique invisible → difficile à comprendre sans lire tout le projet
  • Pas transactionnel si on modifie plusieurs objets
  • Trop de magie nuit à la lisibilité
  • Testabilité réduite si mal structuré

Conclusion

Les EntityListeners (JPA) et AbstractMongoEventListener sont des outils puissants… mais pas toujours adaptés.
Dans une démarche Clean Code, il faut :

  • éviter l’abus de logique métier dans ces hooks
  • préférer des usages techniques simples
  • bien tester et documenter

Astuce : si un développeur ne comprend pas pourquoi un champ est modifié sans appel explicite → c’est que le listener est mal utilisé.

Sources & lectures recommandées

☕ Java a 30 ans : toujours debout, toujours pertinent

Le 23 mai 1995, lors de la conférence SunWorld, Sun Microsystems présentait Java au monde. Un langage orienté objet, avec une promesse qui paraissait audacieuse : “Write Once, Run Anywhere”. Trente ans plus tard, Java est toujours bien vivant. Et contrairement aux nombreuses fois où on a annoncé sa disparition, il continue d’évoluer, de surprendre et surtout, de rassembler.

Des fondations solides pour une longévité remarquable

À sa naissance, Java a conquis rapidement le monde de l’entreprise grâce à la Java Virtual Machine (JVM), garantissant la portabilité du code, et à une robustesse qui le rendait idéal pour les systèmes critiques. Java a traversé toutes les ères : du desktop aux serveurs, des téléphones JavaME aux services cloud-native modernes.

Aujourd’hui, Java est le 3e langage le plus utilisé au monde selon le classement TIOBE 2025. Sa capacité d’adaptation, notamment à travers son écosystème riche, lui permet de rester central dans les architectures modernes.

Java en 2025 : un langage toujours en pleine forme

La version Java 21, sortie en septembre 2023, a été adoptée à une vitesse record. C’est la version LTS qui connaît l’adoption la plus rapide de l’histoire de Java. Elle apporte des améliorations majeures en performance, en gestion mémoire et en productivité grâce à des fonctionnalités comme les records, les classes scellées, et les threads virtuels avec Project Loom.

Java a aussi réussi à s’ancrer dans l’ère de l’IA : aujourd’hui, plus de 8 % des développeurs Java utilisent des assistants IA comme GitHub Copilot pour automatiser des tâches de codage, selon le Java Developer Productivity Report 2024.

Spring Boot et l’écosystème Spring : l’ossature du Java moderne

Impossible de parler de Java sans évoquer Spring. Créé dans les années 2000 pour simplifier le développement Java EE, Spring est devenu une référence pour créer des applications web, API REST, microservices, et bien plus.

Avec Spring Boot, lancé en 2014, l’écosystème a connu une démocratisation massive. Il permet de créer des applications en quelques lignes de code, avec des configurations automatiques et une expérience “developer-friendly”.

En 2024, Spring reste la librairie Java la plus utilisée dans le monde. Des milliers d’entreprises s’en servent pour bâtir leurs systèmes : banques, assurances, e-commerçants, start-ups, tous y trouvent leur compte.

Broadcom, VMware et l’avenir de Spring

Le rachat de VMware par Broadcom en 2023 a fait couler beaucoup d’encre, notamment concernant le sort de l’équipe Spring. Broadcom a confirmé vouloir continuer à soutenir Spring, mais a également introduit une offre commerciale pour le support de Spring Framework 6 et Spring Boot 3, ce qui marque une rupture avec l’approche 100 % open-source historique.

Certains craignent une fragmentation ou un ralentissement de l’innovation, d’autres y voient une opportunité pour professionnaliser encore davantage l’outil.

Une communauté Java toujours aussi vivante

Java vit avant tout grâce à sa communauté. Les Java User Groups (JUG) sont actifs partout dans le monde, organisant conférences, ateliers, meetups. Les Java Champions, sélectionnés pour leurs contributions exceptionnelles, continuent d’animer et de guider la communauté. Et chaque année, des événements comme JavaOne, Devoxx ou Spring I/O attirent des milliers de passionnés.

C’est aussi une communauté de mainteneurs, de créateurs de librairies open source, de formateurs, de coachs techniques qui assurent la relève.

Et demain ?

Annoncé mort à de nombreuses reprises, Java a prouvé à maintes reprises qu’il savait se réinventer. Aujourd’hui, il reste l’un des langages les plus utilisés au monde, que ce soit dans les systèmes critiques, les plateformes cloud, les microservices, ou même les nouvelles applications IA.

Dans un monde où la technologie va vite, Java rappelle que la stabilité, la performance et l’évolutivité sont des qualités intemporelles.

L’avenir de Java, c’est aussi la montée de frameworks modernes comme Micronaut, Quarkus, ou encore Spring Cloud qui explorent la containerisation, les fonctions serverless et Kubernetes.

À 30 ans, Java n’a rien d’un dinosaure. C’est un moteur discret mais puissant du monde numérique, qui avance avec constance et modernité.

Et merci à toutes celles et ceux — développeurs, architectes, mainteneurs, évangélistes, contributeurs, et aussi les équipes Spring passées et présentes — qui, chaque jour, font vivre cette technologie.

Sources & lectures recommandées

Maîtriser l’API Stream en Java : écrire du code élégant et efficace

🚀 Maîtriser l’API Stream en Java : écrire du code élégant et efficace

Introduction

Depuis Java 8, l’API Stream a transformé la manière dont les développeurs manipulent les collections. Elle introduit un style de programmation fonctionnel et déclaratif, permettant d’écrire un code plus concis, lisible, et performant.
Dans cet article, découvrons ensemble l’essentiel de cette API à travers des exemples simples et parlants.

🔹 Qu’est-ce qu’un Stream ?

Un Stream est une suite d’éléments générée à partir d’une source (liste, tableau, fichier, etc.) sur laquelle on applique des opérations successives (filtrage, transformation, agrégation…).
Contrairement aux collections, un stream ne stocke pas de données et ne peut être parcouru qu'une seule fois.

🔹 Création d’un Stream

On crée un Stream à partir d'une liste. Ce flux peut ensuite être filtré, trié, transformé sans modifier la liste d’origine.

image

🔹 Filtrage & transformation

  • .filter(...) sélectionne les prénoms commençant par I

  • .map(...) transforme les prénoms en majuscules

  • .forEach(...) affiche chaque prénom sélectionné

image

🔹 Réduction (reduce)

La méthode .reduce() accumule les éléments pour produire un seul résultat — ici la somme. C’est une alternative élégante aux boucles for.

image

🔹 Groupement avec Collectors

Avec Collectors.groupingBy, on regroupe les prénoms selon leur première lettre. Cela produit une Map où chaque clé est une lettre, et chaque valeur une liste de prénoms.

image

✅ Bonnes pratiques

  • 🔹 Utilisez .limit() et .skip() pour la pagination
    Cela permet de traiter uniquement une portion des données, utile pour afficher une page de résultats ou économiser des ressources.
  • 🔹 Placez toujours .filter() avant .map()
    Filtrer d’abord permet de réduire le nombre d’éléments à transformer, améliorant ainsi les performances.
  • 🔹 Évitez les effets de bord dans map() et filter()
    Ces méthodes doivent rester pures : ne pas modifier d'état externe, ni écrire dans la console, ni interagir avec une base de données.

Conclusion

L’API Stream de Java permet d’écrire du code plus expressif, lisible et performant. Que ce soit pour filtrer, transformer, regrouper ou réduire des données, elle s’adapte parfaitement aux besoins du développement moderne, notamment dans les projets Spring Boot ou les traitements de données.

Nous avons volontairement exploré ici les opérations les plus utilisées pour rester accessibles et concrets.
Notez toutefois qu’il existe de nombreuses autres méthodes dans l’API Stream (comme flatMap(), peek(), distinct(), sorted(), etc.) qui mériteraient un article à part entière.

👉 À vous maintenant d’explorer, de pratiquer et d’intégrer les Streams dans vos projets pour un Java plus moderne et élégant.