使用SpringData创建只读存储库

jpb*_*ult 25 java spring jpa spring-data spring-data-jpa

是否可以使用Spring Data创建只读存储库?

我有一些实体链接到视图和一些子实体,我想为其提供一些存储库,其中包含一些方法findAll(),findOne()以及一些带有@Query注释的方法.我想避免提供类似的方法save(…),delete(…)因为它们没有任何意义,可能会产生错误.

public interface ContactRepository extends JpaRepository<ContactModel, Integer>, JpaSpecificationExecutor<ContactModel> {
    List<ContactModel> findContactByAddress_CityModel_Id(Integer cityId);

    List<ContactModel> findContactByAddress_CityModel_Region_Id(Integer regionId);

    // ... methods using @Query

    // no need to save/flush/delete
}
Run Code Online (Sandbox Code Playgroud)

谢谢!

Oli*_*ohm 50

是的,方法是添加手工制作的基础库.你通常使用这样的东西:

public interface ReadOnlyRepository<T, ID extends Serializable> extends Repository<T, ID> {

  T findOne(ID id);

  Iterable<T> findAll();
}
Run Code Online (Sandbox Code Playgroud)

你现在可以拥有刚刚定义的具体的repos扩展:

public interface PersonRepository extends ReadOnlyRepository<Person, Long> {

  T findByEmailAddress(String emailAddress);
}
Run Code Online (Sandbox Code Playgroud)

定义基本仓库的关键部分是方法声明带有与声明的方法完全相同的签名,CrudRepository如果是这样的话我们仍然可以将调用路由到支持存储库代理的实现bean.我在SpringSource博客上写了一篇关于该主题的更详细的博客文章.

  • 请注意,从 2.0 M3 (Kay) 版本开始,findOne 方法已重命名为 findById,详情请参见 /sf/ask/3087074301/ (3认同)
  • 假设您仍然希望 Spring 创建一些 PagingAndSortingRepository 方法的实现,但不是全部。那么,您将如何创建一个具有相同接口但没有保存和删除方法的“PagingAndSortingReadOnlyRepository”? (3认同)

小智 26

要扩展Oliver Gierke的答案,在更新版本的Spring Data中,您需要在ReadOnlyRepository(父接口)上使用@NoRepositoryBean注释来防止应用程序启动错误:

import org.springframework.data.repository.NoRepositoryBean;
import org.springframework.data.repository.Repository;

@NoRepositoryBean
public interface ReadOnlyRepository<T, ID extends Serializable> extends Repository<T, ID> {

    T findOne(ID id);

    List<T> findAll();

}
Run Code Online (Sandbox Code Playgroud)

  • 获取 init 方法的调用失败;嵌套异常是 org.springframework.data.mapping.PropertyReferenceException: No property findOne found for type` 启动时出错。当删除`T findOne(ID id);`时,它工作正常,但无法通过URL查看单个项目。 (2认同)

Fra*_*eth 7

据我们在文档中可以看到,这可以通过实现org.springframework.data.repository.Repository来实现.


Iqb*_*bal 6

对我来说以下工作有效。Invocation of init method failed; nested exception is org.springframework.data.mapping.PropertyReferenceException: No property findOne found for type使用奥利弗的解决方案,我在启动时遇到错误。

@NoRepositoryBean
public interface ReadOnlyRepository<T,ID> extends Repository<T, ID> {
    Optional<T> findById(ID var1);
    boolean existsById(ID var1);
    Iterable<T> findAll();
    Iterable<T> findAllById(Iterable<ID> var1);
    long count();
}
Run Code Online (Sandbox Code Playgroud)


小智 5

这是用于只读PagingAndSortingRepository

package com.oracle.odc.data.catalog.service.core.repository;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.repository.NoRepositoryBean;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.data.rest.core.annotation.RestResource;

/**
 * Extension of {@link PagingAndSortingRepository} but without modification capabilities
 *
 * @author XYZ
 * @see Sort
 * @see Pageable
 * @see Page
 */
@NoRepositoryBean
public interface ReadOnlyPagingAndSortingRepository<T, ID> extends PagingAndSortingRepository<T, ID> {

    @Override
    @RestResource(exported=false)
    <S extends T> S save(S entity);

    @Override
    @RestResource(exported=false)
    <S extends T> Iterable<S> saveAll(Iterable<S> entities);

    @Override
    @RestResource(exported=false)
    void deleteById(ID id);

    @Override
    @RestResource(exported=false)
    void delete(T entity);

    @Override
    @RestResource(exported=false)
    void deleteAll(Iterable<? extends T> entities);

    @Override
    @RestResource(exported=false)
    void deleteAll();

}
Run Code Online (Sandbox Code Playgroud)

如果您尝试 POST 或 DELETE,您将收到 405(不允许的方法)。