[英]@Transactional is not working in @Service
我正在使用Jersey,Spring和Hibernate开发REST API。 我有这个端点:
@Path("incidences")
public class IncidencesResource {
@InjectParam
IncidencesService incidencesService;
@GET
@Produces(MediaType.APPLICATION_JSON)
public List<Incidence> getIncidences(
@QueryParam("lastupdate") String lastUpdate) {
return incidencesService.getIncidences();
}
和服务:
@Service
public class IncidencesService {
@Autowired
IncidencesDAO incidencesDAO;
@Transactional
public List<Incidence> getIncidences() {
List<Incidence> incidencias = incidencesDao.getIncidences();
return incidences;
}
}
但我得到一个org.hibernate.LazyInitializationException
错误:
无法懒惰地初始化角色集合:com.api.blabla.Incidence.questions,没有会话或会话被关闭
questions
是@OneToMany
财产Incidence
。
如果我在端点方法中放置@Transactional
注释,而不是在服务中,它可以正常工作。 但我知道@Transactional必须放在服务级别。
谢谢。
这并不意味着@Transactional
不起作用。 它正在做你告诉它要做的事情。 该服务返回一个Incidence
实例而没有初始化的questions
集合,并且您试图在服务的事务之外访问该集合(可能是在Jersey尝试将其转换为JSON时)。
在这种情况下,服务必须返回调用者所需的所有数据,这意味着您必须在返回结果之前初始化questions
。 因此,只需在服务方法中为您返回的每个实例调用Hibernate.initialize(incidence.getQuestions())
。
@Transactional
public List<Incidence> getIncidences() {
List<Incidence> incidencias = incidencesDao.getIncidences();
for (Incidence inc : incidencias) {
Hibernate.initialize(inc.getQuestions());
}
return incidencias;
}
您遇到此问题是因为您的交易在您的服务电话上开始和结束。 回想一下Hibernate文档,延迟加载仅适用于Hibernate会话(在这种情况下,hibernate会话以服务调用开始和结束)。 您无法重新连接到hibernate会话(简单地)来初始化集合。
解决这个问题的两种方法:
您可以将获取类型更改为EAGER,以便以后急切加载控制器内引用的问题
对服务进行单独查询以从控制器获取有关事件的问题,并在返回响应之前在视图bean中设置响应
此外,作为更好的实践观点的建议,您可能希望将服务方法中的@Transactional注释更改为@Transactional(readOnly = true),以便更好地执行只读调用。
什么初始化可以在这里看到什么做hibernate-initialize-do
也许你必须手动初始化它。 请试试这个:
@Transactional
public List<Incidence> getIncidences() {
List<Incidence> incidencias = incidencesDao.getIncidences();
for (Incidence inc : incidencias) {
inc.getQuestions().size();
}
return incidencias;
}
解决了! 我在LAZY获取类型中有Incidence -> questions
关系(默认)。 但是,在端点资源方法中,我调用了getQuestions()
。 此代码不在事务内部,因此它抛出了初始化异常。
我通过将@OneToMany
fetch属性@OneToMany
为EAGER来解决它。
谢谢你的回答。 如果你看不到剩下的代码,你很难帮助我...
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.