简体   繁体   中英

Invoke flush() on a repository or service layer?

For example I have the following classes

@Repository
public class JpaUserRepository implements UserRepository {
    ...
    public void create(User user) {
        entityManager.persist(user);
    }
}

@Trensactional
public class UserServiceImpl implements UserService {
    ...
    public void register(User user) {
        try {
            repository.create(user);
        } catch (DataIntegrityViolationException ex) {
            throw new UserAlreadyExistException(user);
        }
    }
}

There is a problem with this approach. Jpa does not throw any exception until the transaction will be commited or EntityManager#flush() will be invoked.

I have two solutions. First is to add a flush() method to the UserRepository interface, and invoke repository.flush() after repository.create(user) in UserServiceImpl#create method. And second is invoke entityManager.flush() after entityManager.persist(user) in JpaUserRepository#create method and document it on the UserRepository interface.

The First solution is not quite flexible because another implementation of UserRepository may not use an instruction cache but must implement flush() method. But as I know JpaRepository from Spring Data uses it. What approach will be best in this situation from the point view of flexibility?

I solved this problem something like that

public class JpaCrudRepository<T, PK extends Serializable> implements CrudRepository<T, PK> {
    private boolean flushOnCreate = true

    public JpaCrudRepository(boolean flushOnCreate) {
        this.flushOnCreate = flushOnCreate;
    }


     /**
     * Persist the given entity to repository and flushes all instructions if isFlushOnCreate() == true
     * @param entity persisted entity
     */
    @Override
    public void create(T entity) {
        entityManager.persist(entity);
        if (flushOnCreate) {
            entityManager.flush();
        }
    }
}

@Repository
public class JpaUserRepository extends JpaCrudRepository<User, Long> implements UserRepository {

    public JpaUserRepository() {
        super(true);
    }
    .....
}

Service layer is remained without changes.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM