在存储库或服务层上调用flush()?

时间:2016-11-04 13:38:25

标签: java jpa spring-data-jpa

例如,我有以下类

@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);
        }
    }
}

这种方法存在问题。在提交事务或调用EntityManager#flush()之前,Jpa不会抛出任何异常。

我有两个解决方案。首先是向UserRepository接口添加flush()方法,并在repository.flush()方法中repository.create(user)之后调用UserServiceImpl#create。第二个是在entityManager.flush()方法中的entityManager.persist(user)之后调用JpaUserRepository#create并将其记录在UserRepository接口上。

第一个解决方案不是很灵活,因为UserRepository的另一个实现可能不使用指令缓存,但必须实现flush()方法。但据我所知,Spring Data的JpaRepository使用它。从灵活性的角度来看,在这种情况下哪种方法最好?

1 个答案:

答案 0 :(得分:0)

我解决了类似的问题

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);
    }
    .....
}

服务层保持不变。