Java @事务性服务在@Service中不起作用

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

我正在用Jersey、Spring和Hibernate开发RESTAPI。我有一个端点:

@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的关系执行,可能是其他关系导致了异常?