为什么在存储库中出现错误“找不到属性”?

ryevplcw  于 2021-08-25  发布在  Java
关注(0)|答案(2)|浏览(481)

我在项目中使用JavaSpring和mongodb存储库。
以下是存储库防御:

@Repository
public interface InfoRepository extends MongoRepository<Info, String> {
    List<InfoDto> findAll();
}

以下是信息防御:

@Document("info")
@Data
public class Info{
    @Id
    private String id = null;
    private String name;
    private String companyName;
    private String email;
    private Address address;
    private String website;
}

以下是有关课堂防御的信息:

@Data
public class InfoDto {
    private String name;
    private String companyName;
    private Address address;
}

当我开始运行项目iu时,出现以下错误:

'findAll()' in '...repository.InfoRepository' clashes with 'findAll()' 
in 'org.springframework.data.mongodb.repository.MongoRepository'; attempting to use incompatible return type

为了防止冲突,我将存储库函数的名称更改为:

List<InfoDto> findAll();

为此:

List<InfoDto> findAllMakeProjection();

但在我进行上述更改并运行函数后,我得到以下错误:

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'infoServiceImpl' defined in file 
[...\InfoServiceImpl.class]: 
Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: 
Error creating bean with name 'infoRepository' defined in ".../repository.InfoRepository" defined in @EnableMongoRepositories 
declared on MongoRepositoriesRegistrar.EnableMongoRepositoriesConfiguration: 
Invocation of init method failed; nested exception is org.springframework.data.mapping.PropertyReferenceException: 
No property findAllMakeProjection found for type Info!

你知道我为什么会出错以及如何修复吗?

7dl7o3gd

7dl7o3gd1#

List<T> findAll() 是mongorepository接口中提供的方法,因此无法在子接口中更改其返回类型。最多,您可以将返回类型更改为列表实现,如 ArrayList<T>LinkedList<T> .
如果将方法名称更改为 List<InfoDto> findAllMakeProjection() ,spring data mongodb将尝试使用属性名构建查询,但没有命名的属性,因此将抛出错误。
但它可以在之前添加任何内容 By 方法名称中的单词,例如。 findAllBy , findEverythingBy , findDataBy . 以后有什么事吗 By 将作为过滤器工作(在条件下),如果我们在之后不添加任何内容 By ,它会像 findAll (无过滤器)
因此,相应地更改方法名称,就可以运行查询了。

qrjkbowd

qrjkbowd2#

这里发生的事情是 findAll() 是为spring数据jpa保留的默认内置存储库方法名。所以如果你介绍你自己的 findAll() 在自定义存储库中(无论是 JPARespositoryMongoRepository )这将与法律冲突 findAll() 由jpa提供。
将方法名称更改为 List<InfoDto> findAllMakeProjection(); 将使jpa使用jpql构建查询,因此它将尝试从方法名称中提取实体属性,除非您使用 @Query 注解。
所以如果你想这么做,应该是 findAllBySomeConditionfindBySomeCondition 前任: findByNameAndCompanyName(), findByEmail(), findAllByCompanyName() 最好的方法是移除 List<InfoDto> findAll(); 在…内 InfoRepository . 不过,你可以打电话

@Autowired
private InfoRepository infoRepository;

.......

infoRepository.findAll();

所以这将返回一个 List<Info> .
而且,您无法直接通过重新生成dto对象列表 MongoRepository 就像你那样。它最初将返回一个模型对象列表( List<Info> ). 为了返回DTO列表,

@Repository
public interface InfoRepository extends MongoRepository<Info, String> {
    @Query(value="select new com.foo.bar.InfoDto(i.name,i.companyName, i.address) from Info i")
    List<InfoDto> findAllInfos();
}

在将地址从实体Map到dto的过程中,您可能需要做一些额外的工作。

相关问题