Java @事务性服务在@Service中不起作用
我正在用Jersey、Spring和Hibernate开发RESTAPI。我有一个端点:Java @事务性服务在@Service中不起作用,java,spring,hibernate,Java,Spring,Hibernate,我正在用Jersey、Spring和Hibernate开发RESTAPI。我有一个端点: @Path("incidences") public class IncidencesResource { @InjectParam IncidencesService incidencesService; @GET @Produces(MediaType.APPLICATION_JSON) public List<Incidence> getInci
@Path("incidences")
public class IncidencesResource {
@InjectParam
IncidencesService incidencesService;
@GET
@Produces(MediaType.APPLICATION_JSON)
public List<Incidence> getIncidences(
@QueryParam("lastupdate") String lastUpdate) {
return incidencesService.getIncidences();
}
@Path(“事件”)
公共类事件资源{
@注入参数
事故服务事故服务;
@得到
@产生(MediaType.APPLICATION_JSON)
公共事件列表(
@QueryParam(“lastupdate”)字符串(lastupdate){
返回IncidenceService.getIncidences();
}
以及服务:
@Service
public class IncidencesService {
@Autowired
IncidencesDAO incidencesDAO;
@Transactional
public List<Incidence> getIncidences() {
List<Incidence> incidencias = incidencesDao.getIncidences();
return incidences;
}
}
@服务
公共类事件服务{
@自动连线
IncidencesDAO IncidencesDAO;
@交易的
公共列表getIncidences(){
List incidencias=incidencesDao.getIncidences();
返回事件;
}
}
但是我得到了一个org.hibernate.LazyInitializationException
错误:
未能延迟初始化角色集合:
com.api.blabla.Incidence.questions,否
会话或会话已关闭
问题
是关联的@OneToMany
属性
如果我将@Transactional
注释放在端点方法中,而不是服务中,它会正常工作。但我知道@Transactional必须放在服务级别
谢谢。这并不意味着@Transactional
不起作用。它正在执行您让它执行的操作。服务返回一个关联
的实例,而不初始化问题的集合
,您正试图在服务的事务之外访问该集合(可能是Jersey试图将其转换为JSON时)
在这种情况下,服务必须返回调用者所需的所有数据,这意味着您必须在返回结果之前初始化questions
。因此,只需在服务方法中为您返回的每个实例调用Hibernate.initialize(incident.getQuestions())
@Transactional
public List<Incidence> getIncidences() {
List<Incidence> incidencias = incidencesDao.getIncidences();
for (Incidence inc : incidencias) {
Hibernate.initialize(inc.getQuestions());
}
return incidencias;
}
@Transactional
公共列表getIncidences(){
List incidencias=incidencesDao.getIncidences();
适用于(发病率公司:发病率){
初始化(inc.getQuestions());
}
复发率;
}
你能在这里看到什么
可能您必须手动初始化它。请尝试以下操作:
@Transactional
public List<Incidence> getIncidences() {
List<Incidence> incidencias = incidencesDao.getIncidences();
for (Incidence inc : incidencias) {
inc.getQuestions().size();
}
return incidencias;
}
@Transactional
公共列表getIncidences(){
List incidencias=incidencesDao.getIncidences();
适用于(发病率公司:发病率){
inc.getQuestions().size();
}
复发率;
}
已解决!我在LAZY获取类型(默认值)中有关联->问题关系。但是,在端点资源方法中,我调用了getQuestions()
。该代码不在事务中,因此引发了初始化异常
我通过将@OneToMany
的fetch属性更改为EAGER解决了这个问题
谢谢您的回答。如果您看不到代码的其余部分,您很难帮助我…您遇到了这个问题,因为您的事务在服务呼叫时开始和结束。
回想一下Hibernate文档,惰性加载只在Hibernate会话中起作用(在本例中,Hibernate会话以服务调用开始和结束)。您不能(简单地)重新连接到Hibernate会话以初始化集合
解决此问题的两种方法:
您可以将fetch类型更改为急切地加载
稍后控制器内部引用的问题
对服务进行单独的查询,从控制器获取事件的问题,并在返回响应之前在视图bean中设置响应
此外,从更好的实践角度来看,建议您将服务方法中的@Transactional注释更改为@Transactional(readOnly=true)为了提高只读调用的性能。在哪里引发异常,在哪个类中?当incidences
转换为JSON时?如果调用Hibernate.initialize(incidences.getQuestions())会怎么样
在您的服务方法中返回事件之前?另一个解决方案是急切地而不是懒洋洋地获取问题,可以使用@OneToMany
的获取
属性进行配置。请编写spring设置xml文件。我得到了相同的错误。这到底是什么意思初始化
一步一步地调试,当我检索一个事件时,我检索嵌套的问题,因为是一对多关系。Hibernate.initialize()
将初始化延迟获取的对象,默认情况下,@OneToMany
iz延迟获取。您是否得到完全相同的异常?是否可以发布stacktrace?这应该对所有转换为JSON的关系执行,可能是其他关系导致了异常?