我刚刚开始使用spring和hibernate。我正在尝试使用DAO创建一些基本服务。
以下是其中之一:
@SuppressWarnings("unchecked")
@Override
public Users findByUserId(int id) {
List<Users> users = new ArrayList<Users>();
if(getSessionFactory() != null) {
try {
session = getSessionFactory().getCurrentSession();
users = session
.createQuery("from Users where id=?")
.setParameter(0, id)
.list();
} catch (HibernateException e) {
LOGGER.error("HibernateException: " + e);
}
}
if (!users.isEmpty()) {
return users.get(0);
} else {
return null;
}
}
我从控制器调用了这个服务:
@RestController
public class JSONController {
@Autowired
private UserDao userDao;
@RequestMapping(value = "/rest/userbyid/{id}",
method = RequestMethod.GET,
headers = "Accept=application/json")
public Users getUserById(@PathVariable("id") int id) {
return userDao.findByUserId(id);
}
}
据我所知,当流程进入控制器时,会话已经关闭。我可以使用openSession()
方法解决这个问题。
我只是想知道有没有更好的方法来处理这个问题?最好还是使用getCurrentSession()
(或任何)。
答案 0 :(得分:1)
返回要在控制器中序列化的实体并不好。想象一下串行器调用所有方法甚至是懒惰的集合。
对于User实例,它调用let说的getProjects()lazy方法,然后为每个Project返回它再次调用getUser()等等。
好的做法是定义服务层并返回仅包含必要字段的DTO(数据传输对象)。
在返回定义深度之前,还有替代方法可以使用unproxy实体。
@SuppressWarnings("unchecked")
protected T unproxy(T entity){
if (entity == null) {
return null;
}
if (entity instanceof HibernateProxy) {
try {
Hibernate.initialize(entity);
} catch (ObjectNotFoundException e) {
return null;
}
entity = (T) ((HibernateProxy) entity).getHibernateLazyInitializer().getImplementation();
}
return entity;
}