【问题标题】:How to implement a Custom Repository using Spring Data JPA?如何使用 Spring Data JPA 实现自定义存储库?
【发布时间】:2018-10-07 19:31:09
【问题描述】:

我正在尝试使用 Spring Data 实现自定义存储库,但出现以下异常:

原因:org.springframework.data.mapping.PropertyReferenceException:找不到类型 {Entity} 的属性 {name}

看起来 @NoRepositoryBean 工作不正常,Spring 正在扫描带有它注释的接口,请问有谁知道如何以正确的方式进行操作?

所有存储库的自定义方法。

@NoRepositoryBean
public interface BaseRepository<T, ID> extends JpaRepository<T, ID> {
    List<T> findAll(Company company);

    EntityManager getEntityManager();
}

public class BaseRepositoryImpl<T, ID> extends SimpleJpaRepository<T, ID> implements BaseRepository<T, ID> {
    private EntityManager entityManager;

    public BaseRepositoryImpl(JpaEntityInformation<T, ?> entityInformation, EntityManager entityManager) {
        super(entityInformation, entityManager);
        this.entityManager = entityManager;
    }

    public EntityManager getEntityManager() {
        return entityManager;
    }

    public List<T> findAll(Company company) {
        //Search by company
    }
}

我还有一些具有自定义方法的存储库,例如:

@NoRepositoryBean
public interface QuestionCustomRepository {
    List<Question> findAllQuestionByTypeAndAsset(Integer[] assetIds);
}

public interface QuestionRepository extends BaseRepository<Question, Integer>, QuestionCustomRepository {
}

@Repository
public class QuestionCustomRepositoryImpl extends BaseRepositoryImpl<Question, Integer> implements QuestionCustomRepository {
    public QuestionCustomRepositoryImpl(JpaEntityInformation<Question, ?> entityInformation, EntityManager entityManager) {
    super(entityInformation, entityManager);
    }

    @Override
    public List<Question> findAllQuestionByTypeAndAsset(Integer[] assetIds) {
    EntityManager entityManager = getEntityManager();
    // Call Native Query
    }
}

测试

@RunWith(SpringRunner.class)
@SpringBootTest(classes = SpringBaseTest.SpringConfiguration.class, properties = "logging.level.org.springframework.data=DEBUG")
@DataJpaTest
public class SpringBaseTest {
    @SpringBootApplication
    @EntityScan(basePackageClasses = Question.class)
    @EnableJpaRepositories(basePackageClasses = QuestionRepository.class, repositoryBaseClass = BaseRepositoryImpl.class)
    public static class SpringConfiguration {
    }
}

class QuestionRepository extends SpringBaseTest {
    @Inject
    QuestionRepository questionRepository;

    @Test
    public void testFindAllByAssetIts() throws Exception {
        List<Question> list = questionRepository.findAllQuestionByTypeAndAsset(new Integer[]{1,2,3});

        assertThat(list).hasSize(3);
    }
}

感谢任何帮助,谢谢。

【问题讨论】:

  • 我不太了解 Spring Data - 但是,在您的第二个示例中,您不想将 @NoRepositoryBean 放在您的第二个接口 QueryRepository 上吗?
  • 关注No property {name} found for type {Entity}。也许您的Question 实体引用了Entity 实体,而Entity 没有name 属性。除此之外我认为你的代码继承太多了。可以简化为public class QuestionCustomRepositoryImpl implements QuestionCustomRepository,只需注入EntityManager bean。无需extends BaseRepositoryImpl。也不要混合使用@SpringBootTest@DataJpaTest,只需使用@DataJpaTest
  • 嗨@RJ.Hwang 按照您的建议应用了更改,但仍然出现相同的错误,该消息No property {method_name} found for Type 是随机的,method_name 来自自定义界面,这就是我认为有问题的原因@NoRepositoryBean.
  • 完全例外是Caused by: java.lang.IllegalArgumentException: Failed to create query for method public abstract java.util.List com.package.product.repository.{EntityName}Repository.{methodName(parameters)}! No property {methodName} found for type {Entity}!感谢您的帮助
  • 还可以尝试在QuestionCustomRepository 接口上删除@NoRepositoryBean,因为它只对您的BaseRepository 接口有用。

标签: spring-boot spring-data-jpa


【解决方案1】:

问题已解决,从接口中删除 @NoRepositoryBean 并留下 BaseRepository

还需要删除@SpringBootTest,因为已经在使用@DataJpaTest

【讨论】:

    猜你喜欢
    • 2015-03-15
    • 2018-10-06
    • 2012-07-15
    • 2017-03-26
    • 2012-06-02
    • 2015-02-13
    • 2016-12-30
    • 1970-01-01
    • 2022-01-25
    相关资源
    最近更新 更多