Java 如何将泛型传递到Spring CRUD存储库';s保存方法
假设我们有三个名为name和id的JPA对象,我用getters+setters为name和id创建了一个接口Java 如何将泛型传递到Spring CRUD存储库';s保存方法,java,spring,generics,spring-data,Java,Spring,Generics,Spring Data,假设我们有三个名为name和id的JPA对象,我用getters+setters为name和id创建了一个接口 class Car implements MetadataObject class Bus implements MetadataObject class Train implements MetadataObject 对于这些JPA对象,我们还有三个存储库: interface CarRepository extends CrudRepository<Car, Long>
class Car implements MetadataObject
class Bus implements MetadataObject
class Train implements MetadataObject
对于这些JPA对象,我们还有三个存储库:
interface CarRepository extends CrudRepository<Car, Long>
interface BusRepository extends CrudRepository<Bus, Long>
interface TrainRepository extends CrudRepository<Train, Long>
这将导致以下错误:
The method save(S) in the type CrudRepository<capture#4-of ? extends MetadataObject, Long> is not applicable for the arguments (MetadataObject)
请注意:我高度简化了示例。我知道在这个例子中,这些JPA类的接口毫无意义。我也知道我的方法毫无意义,但它完美地突出了问题
我的问题是:传递什么来保存,或者如何重写这个函数?这里到底有什么问题?您可以使用此方法定义:
private void <T extends MetadataObject>importMetadata(CrudRepository<T, String> mRepository) {
Optional<T> currentOptional = mRepository.findById(1);
if (currentOptional.isPresent()) {
T current = currentOptional.get();
current.setName("a1");
mRepository.save(current);
}
}
private void importMetadata(crudepository mRepository){
可选currentOptional=mRepository.findById(1);
if(currentOptional.isPresent()){
T current=currentOptional.get();
当前设置名称(“a1”);
mRepository.save(当前);
}
}
我将尝试解释crudepository的save
方法的原因,因此importMetadata
方法在MetadataObject
对象中?或者它是否存在于每个特定对象CarRepository
等中?通过行crudepository,importMetadata方法与服务类中的存储库/jpa分离。谢谢!事实上,我也得出了同样的结论。但这并不能回答我的问题,即为什么上述方法不起作用。它的读数完全相同…因为它无法证明save
使用的类型与findOne
产生的类型完全相同。所有?
类型都不同。严格来说mRepository.save(current)
失败,因为mRepository
这里可能是Car
存储库,而current
实际上是Bus
。使用显式类型T
有助于证明这是不可能的。
The method save(S) in the type CrudRepository<capture#4-of ? extends MetadataObject, Long> is not applicable for the arguments (MetadataObject)
The method importMetadata(CrudRepository<MetadataObject,String>) in the type <...> is not applicable for the arguments (CarRepository)
private void <T extends MetadataObject>importMetadata(CrudRepository<T, String> mRepository) {
Optional<T> currentOptional = mRepository.findById(1);
if (currentOptional.isPresent()) {
T current = currentOptional.get();
current.setName("a1");
mRepository.save(current);
}
}
class C<T> {
public void save (T t) {
// .. whatever
}
}
void f (C<? extends Object> c) {
c.save(new Object());
}