JPA,Spring web - 如何“查找”数据库中不存在的记录

时间:2014-04-14 22:44:56

标签: java spring hibernate jpa model-view-controller

我在Spring上写过网页。我使用Hibernate for JPA。我需要在数据库中找到实体,我从用户那里获得ID。

问题是如果ID不在数据库中 - 我得到NullPointerException。

现在我有:

People p;
try {
  p = peopleManager.findById(id);
  if (p != null) {
    model.addAttribute("message", "user exist, do any action");
  } else {
    model.addAttribute("message", "user NOT exist");
  }
} catch (NullPointerException e) {
  model.addAttribute("message", "user NOT exist");
}
但它看起来很糟糕。我该怎么办呢?

有完整的示例代码:

package com.example.test.entity;

import javax.persistence.Column;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

public class People {  
  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  @Column(name = "id")
  private int id;

  @Column(name="name")
  private String name;

  @Column(name="age")
  private int age;
}
/* ---------------------------------------------------- */
package com.example.test.dao;

import java.util.List;
import com.example.test.entity.People;

public interface PeopleDao {  
    public void save(People people);  
    public void delete(People people);    
    public void update(People people); 
    public List<People> findAll();    
    public People findById(int id);
}
/* ---------------------------------------------------- */
package com.example.test.dao;

import java.util.List;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import com.example.test.entity.People;

@Repository
public class PeopleDaoImpl implements PeopleDao {

  @Autowired
  private SessionFactory sessionFactory;

  @Override
  public void save(People people) {
    this.sessionFactory.getCurrentSession().save(people);    
  }
  @Override
  public void delete(People people) {
    this.sessionFactory.getCurrentSession().delete(people);    
  }
  @Override
  public void update(People people) {
    this.sessionFactory.getCurrentSession().update(people);    
  }
  @Override
  public List<People> findAll() {
    return this.sessionFactory.getCurrentSession().createQuery("from People ORDER BY age").list();
  }
  @Override
  public People findById(int id) {
    return (People) this.sessionFactory.getCurrentSession().get(People.class, id);
  }
}
/* ---------------------------------------------------- */
package com.example.test.service;

import java.util.List;
import com.example.test.entity.People;

public interface PeopleManager {  
  public void save(People people);  
    public void delete(People people);    
    public void update(People people); 
    public List<People> findAll();    
    public People findById(int id);
}
/* ---------------------------------------------------- */
package com.example.test.service;

import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.example.test.dao.PeopleDao;
import com.example.test.entity.People;

@Service
@Transactional
public class PeopleManagerImpl implements PeopleManager {

  @Autowired
  private PeopleDao peopleDao;

  @Override
  public void save(People people) {
    peopleDao.save(people);  
  }
  @Override
  public void delete(People people) {
    peopleDao.delete(people);    
  }
  @Override
  public void update(People people) {
    peopleDao.update(people);
  }
  @Override
  public List<People> findAll() {
    return peopleDao.findAll();
  }
  @Override
  public People findById(int id) {
    return peopleDao.findById(id);
}
/* ---------------------------------------------------- */
package com.example.test.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import com.example.test.entity.People;
import com.example.test.service.PeopleManager;

@Controller
public class PeopleController {  
  @Autowired
  private PeopleManager peopleManager;

  @RequestMapping(value = "/people/{id}", method = RequestMethod.GET)
  public String home(Model model, @PathVariable("id") String id) {    
    People p;
    try {
      p = peopleManager.findById(Integer.parseInt(id));
      if (p != null) {
        model.addAttribute("message", "user exist, do any action");
      } else {
        model.addAttribute("message", "user NOT exist");
      }
    } catch (NullPointerException e) {
      model.addAttribute("message", "user NOT exist");
    }
    return "people";
  }  
}
/* ---------------------------------------------------- */

1 个答案:

答案 0 :(得分:0)

重构您的控制器的空检查。控制器不应该有任何业务逻辑。正确的位置在您的服务类中。

@Override
@Transactional
public People findById(int id) throws ObjectNotFoundException{
    People people = null;        
    people  = peopleDao.findById(id);
    if(people == null){
        throw new ObjectNotFoundException("Couldn't find a People object with id " + id);
    }
    return people;
}

如果您的People对象为null,我会编写一个扩展RuntimeException的自定义异常。

这是最佳做法,因为您可以在所有服务层中重用ObjectNotFoundException。然后使所有控制器方法抛出Exception并调查控制器的全局错误处理。

此外,最佳做法是不将整个服务类注释为@Transactional,标记各个方法。这样,如果您需要向服务添加其他方法,您可以选择是否希望它们在事务上下文中运行。