Реализация репозитория, ориентированного на коллекцию (DDD), с помощью mybatis

Я хочу реализовать репозиторий на основе коллекции на основе mybatis в качестве основного хранилища постоянства. В разделе «Реализация дизайна, управляемого доменом» (см. Главу 12) указано, что интерфейс репозитория должен имитировать Set:

Например:

interface FlightRepository{
   boolean add(Flight f);
   boolean remove(Flight f);
   // finder methods
   Flight findById(Integer id);
}

Реализация mybatis будет выглядеть примерно так (при условии реализации весенней загрузки):

@Mapper
interface FlightMapper{
      int createOrUpdate(Flight flight);
      Flight read(int id);
      int delete(Flight flight);
}

@Component
@Transactional
class FlightRepositoryImpl implements FlightRepository {
    @AutoWired FlightMapper mapper;

    boolean add(Flight f){
        int affectedRows = mapper.createOrUpdate(f);
        if(affectedRows == 1) return true 
        else return false;
    }

    boolean remove(Flight f){
        int affectedRows = mapper.delete(f);
        if (affectedRows == 1) return true
        else return false;
    }

    Flight findById(){
        return mapper.read(id);
    }

}

У меня вопрос, как я могу управлять обновлениями репозитория без saveChanges метода:

Flight f = flightRepository.findById(1);

f.setDepartureTime(...);
f.setArrivalTime(...);

// flightRepository.saveChanges(); ??

Одним из вариантов реализации было бы создание репозитория копии исходного объекта Flight перед его возвратом клиенту. Когда приходит время сохранять изменения, он сравнивает свою внутреннюю копию с объектом полета, возвращаемым клиенту. Если внутренняя копия не соответствует объекту, возвращенному клиенту, то хранилище сохраняемости будет обновлено версией клиента (с использованием flightMapper.createOrUpdate()).

Однако как я могу запустить эту логику, не заставляя клиента вызывать явный saveChanges() метод? Это означало бы, что мне нужно было бы каким-то образом подключиться к времени жизни объекта Repository, используя весеннюю загрузку (другими словами, запускать обновления до того, как транзакция будет зафиксирована.


person BigONotation    schedule 06.01.2019    source источник
comment
Похоже, что в Java атрибут @Transactional работает с ORM и метод saveChanges вызывается автоматически. stackoverflow.com/questions/46708063 /   -  person Muflix    schedule 05.08.2019


Ответы (1)


Вы можете что-то сделать перед фиксацией, реализовав TransactionSynchronization с использованием TransactionSynchronizationAdapter для удобства:

@Bean
public class TransactionEventsListener extends TransactionSynchronizationAdapter {

    @Override
    public void beforeCompletion() {
        // do something before commit
    }
}
person Roman Konoval    schedule 08.01.2019