任何人都可以告诉我,我可以在JAXWS Web服务方法中返回Hibernate Entities作为返回值吗?
确实我有一些这样的实体:
@Entity
public class Parent {
...
private Childone childoneByChildoneid;
@ManyToOne
public
@javax.persistence.JoinColumn(name="ChildOneId",referencedColumnName="Id")
Childone getChildoneByChildoneid() {
return childoneByChildoneid;
}
public void setChildoneByChildoneid(Childone childoneByChildoneid) {
this.childoneByChildoneid = childoneByChildoneid;
}
...
}
@Entity
public class Childone {
...
private Collection<Parent> parentsById;
@OneToMany(mappedBy = "childoneByChildoneid")
public Collection<Parent> getParentsById() {
return parentsById;
}
public void setParentsById(Collection<Parent> parentsById) {
this.parentsById = parentsById;
}
...
}
并提供这样的服务:
@Stateless
@WebService()
public class MasterDataService {
@EJB
private MasterDataManager manager;
@WebMethod
public Parent getParent(int parentId) {
return manager.getParent(parentId);
}
}
@Stateless
public class MasterDataManager {
@PersistenceContext
EntityManager em;
public Parent getParent(int parentId) {
Parent parent = (Parent) em.createQuery(
"select p from Parent p where p.id=:parentId")
.setParameter("parentId", parentId).getSingleResult();
return parent;
}
}
当我从客户端调用此Web方法时,我得到LazyInitializationException异常:(
我测试Serializable和Cloneable接口并覆盖克隆方法,但不幸的是它不起作用,我在管理器中使用了em.detach(parent),但它仍然不能正常工作。
任何人都可以帮助我吗?
tnax
答案 0 :(得分:7)
这是值得商榷的。通常,您有两种选择:
返回实体,但请确保它们已初始化。使用@*ToMany
标记fetch=FetchType.EAGER
或使用Hibernate.initialize(..)
。异常的原因是默认情况下,在请求之前,不会从数据库中提取实体中的所有集合。但是当你从jax-ws序列化程序请求它们时,hibernate会话已经关闭。从技术上讲,你可以有一些OpenSessionInViewIntercepetor
,但我认为JAX-WS没有现成的东西,写一个可能是个问题。如果您不想传输这些集合,可以使用@XmlTransient
(或@JsonIgnore
注释它们,具体取决于序列化技术)。它使实体有点混乱,但我仍然更喜欢它来编码重复。
使用DTO(数据传输对象) - 将所有数据从实体传输到具有类似结构的新对象,该对象将由Web服务公开。再次,您必须确保在休眠会话激活时填充DTO
我更喜欢第一个选项,因为它需要更少的biolerplate代码,但我同意在使用它时应该非常小心实体状态管理。