【问题标题】:Generic DAO cause stack overflow通用 DAO 导致堆栈溢出
【发布时间】:2017-06-04 17:39:21
【问题描述】:

您好,我的 Spring/Hibernate 项目有问题。我试图为 DAO 和服务实现通用类,并使用一个具体的实现在屏幕上显示一些东西。一切开始都没有错误,但是如果我想创建一个新项目,在提交表单后它会引发 Stack Overflow 错误(见下图)。我不知道问题出在哪里。我希望这里有人可以帮助我。下面你可以看到我所有的代码,如果需要,可以添加 jsp 或配置文件。感谢您的宝贵时间。

GenericDaoImpl

@SuppressWarnings("unchecked")
@Repository
public abstract class GenericDaoImpl<T, PK extends Serializable> implements IGenericDao<T, PK> {

    @Autowired
    private SessionFactory sessionFactory;

    protected Class<? extends T> entityClass;

     public GenericDaoImpl() {
        Type t = getClass().getGenericSuperclass();
        ParameterizedType pt = (ParameterizedType) t;
        entityClass = (Class<? extends T>) pt.getActualTypeArguments()[0];
     }

    protected Session currentSession() {
        return sessionFactory.getCurrentSession();
    }

    @Override
    public PK create(T t) {
        return (PK) currentSession().save(t);

    }

    @Override
    public T read(PK id) {
        return (T) currentSession().get(entityClass, id);
    }

    @Override
    public void update(T t) {
        currentSession().saveOrUpdate(t);   
    }

    @Override
    public void delete(T t) {
        currentSession().delete(t);

    }

    @Override
    public List<T> getAll() {
        return currentSession().createCriteria(entityClass).list();
    }

    @Override
    public void createOrUpdate(T t) {
        currentSession().saveOrUpdate(t);   
    }

GenericServiceImpl

@Service
public abstract class GenericServiceImpl<T, PK extends Serializable> implements IGenericService<T, PK>{

     private IGenericDao<T, PK> genericDao;

    public GenericServiceImpl(IGenericDao<T,PK> genericDao) {
        this.genericDao=genericDao;
    }

    public GenericServiceImpl() {
    }


    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public PK create(T t) {
        return create(t);
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, readOnly = true)
    public T read(PK id) {
        return genericDao.read(id);
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public void update(T t) {
        genericDao.update(t);
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public void delete(T t) {
        genericDao.delete(t);

    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public void createOrUpdate(T t) {
        genericDao.createOrUpdate(t);   
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, readOnly = true)
    public List<T> getAll() {
        return genericDao.getAll();
    }

}

ProjectDaoImpl

@Repository
public class ProjectDaoImpl extends GenericDaoImpl<Project, Integer> implements IProjectDao{

}

项目服务实现

@Service
public class ProjectServiceImpl extends GenericServiceImpl<Project, Integer> implements IProjectService {


    @Autowired
    public ProjectServiceImpl(@Qualifier("projectDaoImpl") IGenericDao<Project, Integer> genericDao) {
        super(genericDao);
    }

}

项目控制器

public class ProjectController {

     @Autowired(required = true)
     private IProjectService projectService;

    @RequestMapping(value = "/projects", method = RequestMethod.GET)
    public String listProjects(Model model){
        model.addAttribute("project", new Project());
        model.addAttribute("listProjects", projectService.getAll());
        return "project";
    }

    //for add and update role both
    @RequestMapping(value = "/project/add", method = RequestMethod.POST)
    public String addProject(@ModelAttribute("project") Project p){
        if( p.getId() == 0){
            //new role, add it
            projectService.create(p);
        } else {
            //existing role, call update
           projectService.update(p);
        }
        return "redirect:/projects";
    }

    @RequestMapping("/remove/{id}")
    public String deleteProject(@PathVariable("id") int id){
        projectService.delete(projectService.read(id));
        return "redirect:/projects";
    }

    @RequestMapping("edit/{id}")
    public String editProject(@PathVariable("id") int id, Model model){
        model.addAttribute("project", projectService.read(id));
        model.addAttribute("listProjects", projectService.getAll());

        return "project";
    }

}

【问题讨论】:

  • 你认为public PK create(T t) { return create(t); } 做了什么,你为什么这么认为?或者换一种方式问:你为什么不认为它在呼唤自己?您必须坐在那里盯着那行代码(错误消息清楚地突出显示)多长时间才能看到您可能忘记使用genericDao. 进行呼叫限定?

标签: java spring hibernate generics


【解决方案1】:
@Override
@Transactional(propagation = Propagation.REQUIRED)
public PK create(T t) {
    return create(t);
}

此方法无条件调用自身。这只会导致 StackOverflowError。

你的意思是这样做吗?

@Override
@Transactional(propagation = Propagation.REQUIRED)
public PK create(T t) {
    return genericDao.create(t);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-05-21
    • 2014-02-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-11
    • 2015-12-21
    相关资源
    最近更新 更多