我使用 Spring MVC + Hibernate 开发了一个 webapp,并使用了三层,Controller 层、Service 层和 Dao 层。
现在我想为我的 webapp 提供一个 REST api。
因为我有一个 GenericDao,它提供了像 find(id)、findAll()、findByProperty() 这样的通用方法,我想我可以跳过 Api 控制器中的服务层并将 daos 注入控制器本身,否则我将不得不创建类- 这些通用查找的每个域对象的特定方法,findAll 方法,当我只想预设原始数据时,这是一件很痛苦的事情。
我的第一个更通用的问题是关于这个架构决策。这是一个好的解决方案吗?
我的第二个(也是主要)问题是我在使用@Transactional
休眠会话打开时注释我的控制器方法时遇到了麻烦。似乎它根本不起作用。
我什至创建了这个问题中所说的界面。
IApi控制器
@Controller
public interface IApiController {
@ResponseBody
public String getStation(Long id);
@ResponseBody
public String getStations();
}
ApiController
@Controller
@RequestMapping("/api")
public class ApiController extends BaseApiController implements IApiController {
@Autowired
private IStationDao stationDao;
@RequestMapping(value = "stations/{id}", produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
@Transactional(readOnly=true)
public String getStation(@PathVariable Long id){
Station station = stationDao.findById(id);
return pack(station);
}
@Override
@RequestMapping(value = "stations", produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
@Transactional(readOnly=true)
public String getStations() {
List<Station> stations = stationDao.findAll();
return pack(stations);
}
}
当我打电话时,api/stations
我得到一个HibernateException: No Session found for current thread
上下文配置
<context:component-scan base-package="my controller package" />
<mvc:annotation-driven />
<context:annotation-config />
<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="SessionFactory" />
</bean>
<bean id="SessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation">
<value>classpath:hibernate.cfg.xml</value>
</property>
<property name="mappingLocations">
<list>
<value>classpath*:/hbm/*.hbm.xml</value>
</list>
</property>
</bean>