Spring CrudRepository:为什么要发明一个新的泛型类型S.

时间:2014-10-13 17:58:10

标签: java spring generics

请你给我一个提示为什么在CrudRepository界面中的“保存”方法中有一个新的通用类型“S”被发明。 (见org.springframework.data.repository.CrudRepository

这是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);

     ...

     /**
      * Deletes a given entity.
      * 
      * @param entity
      * @throws IllegalArgumentException in case the given entity is (@literal null}.
      */
      void delete(T entity);
}

请注意,在第二种方法“删除”中,同一实体的类型为T. 方法“save”表示它返回一个类型为“S”的对象。所以这是不可能实现方法“保存”这样说:

@Override
public <S extends MyType> S save(S entity) {
    save(entity);
    return findOne(entity.getMyTypeId()); // Type mismatch: cannot convert from MyType to S
}

另一个问题是如何更好地实施“保存”方法?

2 个答案:

答案 0 :(得分:3)

目的是通常,Spring *Repository接口是由Spring Data自动实现的,而不是手工实现的,并且知道您将获得相同类型的对象很方便在您放入save操作之外。特别是对于面向文档的数据存储,看到子类与超类保持在同一个存储库中并使用S extends T作为参数并不罕见和返回类型确保您可以使用与保存之前相同的接口继续使用持久化对象。

答案 1 :(得分:0)

似乎保存的实现之一可以是:

@Override
public <S extends MyType> Iterable<S> save(Iterable<S> entities) {
    List<S> result = new ArrayList<S>();
    for (S entity : entities) {
        result.add(save(entity));
    }
    return result;
}