编写通用存储库和服务时绑定不匹配错误

时间:2016-01-11 16:39:16

标签: java spring generics

我正在写一个Spring MVC网络应用程序。有三个主要的域实体:User,Project,Task。此外,还有一些常见的操作,因此我尝试编写通用接口和抽象类来聚合通用逻辑。

有表示存储库行为的GenericRepository接口:

package org.example.btracker.repository;

import java.io.Serializable;
import java.util.List;

public interface GenericRepository<E, K extends Serializable> {
    K save(E entity);
    List<E> findSeveralById(K id);
    E findOneById(K id);
    K update(E changedEntity);
    void delete(K id);
}

有AbstractGenericRepository,其中实现了共享逻辑:

package org.example.btracker.repository;

import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;

@SuppressWarnings("unchecked")
public abstract class AbstractGenericRepository<E, K extends Serializable> implements GenericRepository<E, K> {

    @Autowired
    private SessionFactory sessionFactory;

    protected Session session;

    protected Class<E> type;


    public AbstractGenericRepository() {
        Type t = getClass().getGenericSuperclass();
        ParameterizedType pt = (ParameterizedType) t;
        type = (Class<E>) pt.getActualTypeArguments()[0];

        session = getSession();
    }

    //method implementation omitted for brevity
    //implemented all but findSeveralById method which is specific for each entity

    private Session getSession() {
        return sessionFactory.getCurrentSession();
    }
}

每个实体有三个接口。以下是Project实体的代码:

package org.example.btracker.repository;

import org.example.btracker.domain.Project;

public interface ProjectRepository extends GenericRepository<Project, Integer> {

}

每个实体都有上述接口的具体实现。以下是具有findSeveralById方法特定实现的Project实体的代码:

package org.example.btracker.repository;

import java.util.List;

import org.example.btracker.domain.Project;

public class ProjectRepositoryImpl extends AbstractGenericRepository<Project, Integer> implements ProjectRepository {

    @Override
    public List<Project> findSeveralById(Integer id) {
        //TODO write an implementation
        return null;
    }
}

有一个表示常见服务行为的GenericService接口:

package org.example.btracker.service;

import java.io.Serializable;
import java.util.List;

public interface GenericService<E, K extends Serializable> {
    K create(E entity);
    List<E> getAll(K id);
    E getOne(K id);
    K update(E changedEntity);
    void delete(K id);
}

还有一个抽象服务,其中实现了共享逻辑:

package org.example.btracker.service;

import java.io.Serializable;
import java.util.List;

import org.example.btracker.repository.GenericRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

@Transactional
public abstract class AbstractGenericService<E, K extends Serializable, R extends GenericRepository<E, K>> implements GenericService<E, K> {

    @Autowired
    protected R repository;

    //method implementation omitted for brevity

}

每个实体有三个接口。以下是具有特定连接方法签名的Project实体的代码:

package org.example.btracker.service;

import org.example.btracker.dto.ProjectDto;

public interface ProjectService extends GenericService<ProjectDto, Integer> {
    Integer join(Integer id);
}

上述接口有三种具体实现。以下是Project实体的代码,其中包含join方法的实现:

package org.example.btracker.service;

import org.example.btracker.dto.ProjectDto;
import org.example.btracker.repository.ProjectRepository;
import org.example.btracker.repository.ProjectRepositoryImpl;
import org.springframework.stereotype.Service;

@Service
public class ProjectServiceImpl extends AbstractGenericService<ProjectDto, Integer, ProjectRepository> implements ProjectService {

    @Override
    public Integer join(Integer id) {
        // TODO write an implementation
        return null;
    }
}

在ProjectServiceImpl类中,我收到错误:

Bound mismatch: The type ProjectRepository is not a valid substitute for the bounded parameter <R extends GenericRepository<E,K>> of the type AbstractGenericService<E,K,R>

我无法理解什么是错的。请指教! 提前谢谢。

1 个答案:

答案 0 :(得分:2)

你定义了:

public class ProjectServiceImpl extends AbstractGenericService<ProjectDto, Integer, ProjectRepository>
public abstract class AbstractGenericService<E, K extends Serializable, R extends GenericRepository<E, K>>

此处R extends GenericRepository<E,K>ProjectRepository

public interface ProjectRepository extends GenericRepository<Project, Integer>

因此,E类型为ProjectK类型为Integer
在您的ProjectServiceImpl E类型为ProjectDto,而不是Project