当我尝试调用(下面的代码)通用的crudrepository接口的save方法时,出现下面的编译错误。
我应该在crudrepository和IDateDescriptorRepository之间创建一个接口吗?
我是否在crudrepository中遗漏了一个重要内容(例如我应该为所有描述符实体使用一个存储库)?
我是否在当前代码中缺少某些内容以使save()调用正常工作?
错误:
DescriptorRepositoryHelper.java:32: error: no suitable method found for save(Descriptor)
return descriptorRepoMap.get(descriptor.type).save(descriptor);
^
method CrudRepository.<S#1>save(S#1) is not applicable
(inferred type does not conform to upper bound(s)
inferred: Descriptor
upper bound(s): CAP#1)
method CrudRepository.<S#2>save(Iterable<S#2>) is not applicable
(cannot infer type-variable(s) S#2
(argument mismatch; Descriptor cannot be converted to Iterable<S#2>))
where S#1,S#2 are type-variables:
S#1 extends CAP#1 declared in method <S#1>save(S#1)
S#2 extends CAP#1 declared in method <S#2>save(Iterable<S#2>)
where CAP#1 is a fresh type-variable:
CAP#1 extends Descriptor from capture of ? extends Descriptor
代码:
DescriptorRepositoryHelper
@Component
public class DescriptorRepositoryHelper {
@Autowired
private IDateDescriptorRepository dateDescriptorRepository;
private Map<DescriptorTypes,CrudRepository<? extends Descriptor,Integer>> descriptorRepoMap = new HashMap<>();
public DescriptorRepositoryHelper() {
descriptorRepoMap.put(DescriptorTypes.DATE,dateDescriptorRepository);
}
Descriptor save(Descriptor descriptor) {
return descriptorRepoMap.get(descriptor.type).save(descriptor);
}
...
IDateDescriptorRepository
public interface IDateDescriptorRepository extends CrudRepository<DateDescriptor, Integer> {
}
DateDescriptor
@Entity
public class DateDescriptor extends Descriptor {
...
答案 0 :(得分:0)
首先查看CrudRepository
的源代码。
public interface CrudRepository<T, ID extends Serializable> extends Repository<T, ID> {
/**
* Saves a given entity. Use the returned instance for further operations as the save operation might have changed the
* entity instance completely.
*
* @param entity
* @return the saved entity
*/
<S extends T> S save(S entity);
// Remainder omitted.
}
这将允许您保存T
的任何子类型并返回相同的子类型。您可以保存Descriptor
的任何子类型,包括但不限于DateDescriptor
。像这样更改代码,以使其正常工作。
public interface IDateDescriptorRepository extends CrudRepository<Descriptor, Integer> {
}
public class DescriptorRepositoryHelper {
@Autowired
private IDateDescriptorRepository dateDescriptorRepository;
public DescriptorRepositoryHelper() {
}
Descriptor save(Descriptor descriptor) {
return dateDescriptorRepository.save(descriptor);
}
}
通过该实现,不再需要使用descriptorRepoMap
。由于可以使用相同的存储库来保存Descriptor
的任何子类型,因此您将获得保存为return的确切信息。
特别是对于面向文档的数据存储,通常不会看到子类与超类保留在同一存储库中,并且使用S扩展T作为参数使其在支持此类用例时更加灵活。