我可以将 Hibernate 实体作为 JAXWS Web 服务方法中的返回值返回吗?
谁能对我说,我可以在 JAXWS Web 服务方法中将 Hibernate 实体作为返回值返回吗?
事实上,我有一些像这样的实体:
@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 异常 :(
我测试 Serialized 和 Cloneable 接口并覆盖克隆方法,但不幸的是它不起作用,我使用 em 中,但它仍然不起作用。
有人可以帮助我吗?
.detach(parent) 在管理器
Can any one say to me that can I return Hibernate Entities as return value in JAXWS web service methods!?
Indeed I have some Entities like these:
@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;
}
...
}
And have a service like this:
@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;
}
}
When I call this web method from client I get LazyInitializationException exception :(
I test Serializable and Cloneable interfaces and override clone method but unfortunately it doesn't work, I use em.detach(parent) in manager but it doesn't work still.
Can any one help me?
tnax
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这是有争议的。通常,您有两个选择:
返回实体,但确保它们已初始化。使用
fetch=FetchType.EAGER
标记@*ToMany
或使用Hibernate.initialize(..)
。异常的原因是,默认情况下,在请求之前不会从数据库中获取实体中的所有集合。但是当您从 jax-ws 序列化器请求它们时,hibernate 会话已经关闭。从技术上讲,您可以拥有一些OpenSessionInViewIntercepetor
,但我认为 JAX-WS 没有现成的东西,并且编写一个可能是一个问题。如果您不想传输这些集合,可以使用@XmlTransient
(或@JsonIgnore
,具体取决于序列化技术)对它们进行注释。它使实体有点混乱,但我仍然更喜欢它而不是代码重复。使用 DTO(数据传输对象)- 将所有数据从实体传输到具有类似结构的新对象,该对象将由 Web 服务公开。同样,您必须确保在休眠会话处于活动状态时填充 DTO
我更喜欢第一个选项,因为它需要较少的 biolerplate 代码,但我同意在使用它时应该非常小心实体状态管理。
It is debatable. Generally, you have two options:
return the entities, but make sure they are initialized. Either mark the
@*ToMany
withfetch=FetchType.EAGER
or useHibernate.initialize(..)
. The reason for the exception is that by default all collections in entities are not fetched from the database until requested. But when you request them from the jax-ws serializer, the hibernate session is already closed. Technically, you can have someOpenSessionInViewIntercepetor
but I don't think there's something ready-to-use with JAX-WS, and it might be a problem to write one. If you don't want to transfer these collections, you can annotate them with@XmlTransient
(or@JsonIgnore
, depending on the serialization technique). It makes the entity somewhat of a mess, but I still prefer it to code duplication.Use DTOs (data transfer objects) - transfer all data from the entity to a new object with a similar structure, that will be exposed by the web service. Again you'd have to make sure you are populating the DTO when the hibernate session is active
I prefer the first option, because it requires less biolerplate code, but I agree one should be very careful with entity state management when using it.