2017-02-07 1 views
0

Je dois vérifier les modifications dans une ancienne base de données DBF intégrée qui est remplie par une ancienne application tierce. Je n'ai pas accès au code source de cette application et ne peux pas mettre le déclencheur ou quoi que ce soit sur la base de données. Pour les contraintes métier, je ne peux pas changer cela ...Comment écouter le changement dans une collection?

Mon objectif est de capturer de nouveaux enregistrements, enregistrements supprimés et enregistrements modifiés d'une table (~ 1500 enregistrements) de cette base de données avec une application Java pour d'autres processus. La base de données est accessible dans mon application Spring par le biais du pilote JPA/Hibernate avec HXTT DBF.

Je cherche maintenant un moyen de capturer efficacement les modifications apportées par l'application tierce dans la base de données. Dois-je lire périodiquement la table entière et vérifier si chaque enregistrement est toujours inchangé ou appliquer n'importe quel type de diff dans deux lectures? Y a-t-il une sorte de "déclencheur" que je peux définir dans mon application Java? Comment écouter correctement ces changements?

Répondre

1

Il n'existe aucun mécanisme JPA permettant d'obtenir des rappels à partir d'une base de données lorsque les données changent.

Les seules options sont de créer votre propre détection de changement. En général, vous commencerez par détecter les entités ajoutées, supprimées et qui existent encore. Pour la fois qui existe encore, vous devrez vérifier si elles sont modifiées, donc l'entité a besoin d'une méthode equals(). Une entité est identifiée par sa clé primaire, donc vous aurez besoin de l'ensemble de toutes les clés primaires, une fois que vous avez utilisé les méthodes Sets de Guava pour produire les 3 ensembles ajoutés, supprimés et existants (avant et maintenant), comme ça.

List<MyEntity> old = new ArrayList<>(); // load from the DB last time 
List<MyEntity> current = new ArrayList<>(); // loaded from DB now 

Map<Long, MyEntity> oldMap = old.stream().collect(Collectors.toMap(MyEntity::getId, Function.<MyEntity>identity())); 
Map<Long, MyEntity> currentMap = current.stream().collect(Collectors.toMap(MyEntity::getId, Function.<MyEntity>identity())); 

Set<Long> oldKeys = oldMap.keySet(); 
Set<Long> currentKeys = currentMap.keySet(); 

Sets.SetView<Long> deletedKeys = Sets.difference(oldKeys, currentKeys); 
Sets.SetView<Long> addedKeys = Sets.difference(currentKeys, oldKeys); 
Sets.SetView<Long> couldBeChanged = Sets.intersection(oldKeys, currentKeys); 

for (Long id : couldBeChanged) { 
    if (oldMap.get(id).equals(currentMap.get(id))) { 
     // entity with this id was changed 
    } 
}