是否有必要为每个实体创建存储库和服务?

时间:2015-06-08 20:47:16

标签: java spring hibernate jpa

我正在使用Hibernate + Spring和一个数据库来保存我的实体。我已经使用JpaRepository来创建我的存储库,但即便如此,似乎我必须为每个实体创建一个扩展JpaRepository的接口。最糟糕的是,我正在为每个实体创建一个服务。他们都非常相似。

有什么方法可以创建通用服务和通用存储库?是否真的有必要实施它们中的每一个?

目前,我有这样的存储库:

@Repository
public interface PhaseRepository extends JpaRepository<Phase, Serializable> {

}

和这样的服务:

@Service
public class PhaseService {
    @Autowired
    PhaseRepository repository;

    @Transactional
    public Phase create(Phase entity) {
        return repository.save(entity);
    }

    @Transactional(rollbackFor = EntityNotFound.class)
    public Phase delete(int id) throws EntityNotFound {
        Phase deleted = repository.findOne(id);
        if (deleted == null) {
            throw new EntityNotFound();
        }
        repository.delete(deleted);
        return deleted;
    }

    @Transactional(rollbackFor = EntityNotFound.class)
    public Phase update(Phase entity) throws EntityNotFound {
        Phase updated = repository.findOne(entity.getId());

        if (updated == null) {
            throw new EntityNotFound();
        }

        repository.saveAndFlush(entity);
        return updated;
    }

    public Phase findById(int id) throws EntityNotFound {
        Phase entity = repository.findOne(id);

        if (entity == null) {
            throw new EntityNotFound();
        }

        return entity;
    }
}

我正在使用12个实体,每个人都有相同的服务方法。

谢谢!

2 个答案:

答案 0 :(得分:3)

可能你需要12个存储库。但也许你不会需要12项服务。服务可以处理对多个存储库的访问。这取决于你的逻辑以及&#34;重要的&#34;是每个实体。

例如,如果您拥有实体User和Address,则可以使用UserRepository和AddressRepository。但只有UserService,使用addAddress(用户用户,地址)等方法......

总而言之,我建议您根据业务逻辑而不是一堆CRUD来组织服务

答案 1 :(得分:0)

您需要12个存储库,因为Spring初始化您声明的接口的实例。 Spring已经做得很好,我在这里看不到问题。想象一下当时必须通过样板JDBC代码实现这些存储库的情况。

但是您不需要自动为您的存储库提供服务。为您的应用程序创建服务,并在其中自动装配必要的存储库。但是我已经创建了一个示例代码,如果你想要没有复制粘贴代码的通用服务:

public abstract class AbstractService<T extends AbstractEntity, K extends Serializable> {

    protected JpaRepository<T, K> repository;

    public AbstractService(final JpaRepository<T, K> repository) {
        this.repository = repository;
    }

    @Transactional(rollbackFor = EntityNotFound.class)
    public T delete(final K id) throws EntityNotFound {
        final T deleted = this.repository.findOne(id);
        if (deleted == null) {
            throw new EntityNotFound();
        }
        this.repository.delete(deleted);
        return deleted;
    }

    ...

}

实现类将是:

@Service
public class PhaseService extends AbstractService<PhaseEntity, Integer> {

    @Autowired
    public PhaseService (final PhaseRepository repository) {
        super(repository);
    }

}

还有一些提示:

  • 您不需要EntityNotFound异常。只需检查实体是否为空。
  • 而不是Serializable使用主键强类型 - 例如Integer。