Java 我可以在JAXWS web服务方法中返回Hibernate实体作为返回值吗?

Java 我可以在JAXWS web服务方法中返回Hibernate实体作为返回值吗?,java,web-services,hibernate,jpa,jax-ws,Java,Web Services,Hibernate,Jpa,Jax Ws,有人能告诉我,我可以在JAXWS web服务方法中将Hibernate实体作为返回值返回吗 事实上,我有一些类似的实体: @Entity public class Parent { ... private Childone childoneByChildoneid; @ManyToOne public @javax.persistence.JoinColumn(name="ChildOneId",referencedColumnName="Id")

有人能告诉我,我可以在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;
    }
...
}
当我从客户端调用此web方法时,我得到LazyInitializationException异常:(

我测试了可序列化和可克隆的接口,并覆盖了克隆方法,但不幸的是,它不起作用,我在manager中使用em.detach(parent),但它仍然不起作用

有人能帮我吗


tnax

这是有争议的。通常,您有两种选择:

  • 返回实体,但确保它们已初始化。使用
    fetch=FetchType.EAGER
    标记
    @*ToMany
    ,或使用
    Hibernate.initialize(…)
    。出现异常的原因是,默认情况下,实体中的所有集合在被请求之前都不会从数据库中获取。但是当您从jax ws序列化程序请求它们时,hibernate会话已经关闭。从技术上讲,您可以使用一些
    OpenSessionInviewinterceptor
    ,但我认为还没有准备好-与JAX-WS一起使用,编写一个可能会有问题。如果您不想传输这些集合,可以使用
    @xmltransive
    (或
    @JsonIgnore
    ,取决于序列化技术)对它们进行注释。这会使实体有点混乱,但我仍然喜欢它而不是代码复制

  • 使用DTO(数据传输对象)-将所有数据从实体传输到具有类似结构的新对象,该对象将由web服务公开。同样,您必须确保在hibernate会话处于活动状态时填充DTO

我更喜欢第一个选项,因为它需要更少的biolerplate代码,但我同意在使用它时应该非常小心实体状态管理。

您好亲爱的Bozho:)我喜欢您更喜欢第一个选项,但有一个大问题。也许我们有一个包含很多关系的大对象,我们不喜欢返回所有这些关系。换句话说,我们可能会在一个场景中返回这个带有一些关系的大对象,在另一个场景中返回带有另一个关系的大对象。这个问题有解决办法吗?谢谢你的关注。
@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;
    }
}