2017-02-07 12 views
0

Мне нужно проверить изменения в старой встроенной базе данных DBF, которая заполнена старым сторонним приложением. Я не имею доступа к исходному коду этого приложения и не могу поместить триггер или что-то еще в базу данных. Для бизнес-ограничений я не могу это изменить ...Как слушать изменения в коллекции?

Моя цель - захватить новые записи, удаленные записи и измененные записи из таблицы (~ 1500 записей) этой базы данных с помощью приложения Java для дальнейших процессов. База данных доступна в моем приложении Spring, хотя JPA/Hibernate с драйвером DBX HXTT.

Я ищу способ эффективного захвата изменений, сделанных сторонним приложением в базе данных.

Должен ли я периодически читать всю таблицу и проверять, не изменилась ли каждая запись или применить какой-либо diff в двух чтениях? Есть ли какой-то «триггер», который я могу установить в своем приложении Java? Как правильно слушать эти изменения?

ответ

1

Нет механизма JPA для получения обратных вызовов из базы данных при изменении данных.

Единственные варианты - создать собственное обнаружение изменений. Обычно вы начинаете с определения того, какие объекты были добавлены, удалены и которые все еще существуют. Для того, что когда-то все еще существует, вам нужно будет проверить, изменены ли они, поэтому субъекту нужен метод equals(). Сущность идентифицируется с помощью первичного ключа, поэтому вам нужно будет получить набор всех первичных ключей, если у вас есть, что вы можете легко использовать методы Guava Sets для создания 3 наборов добавленных, удаленных и существующих (до и теперь), как это.

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