我可以将 Hibernate 实体作为 JAXWS Web 服务方法中的返回值返回吗?

发布于 2024-11-02 04:24:34 字数 1662 浏览 2 评论 0原文

谁能对我说,我可以在 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

趁年轻赶紧闹 2024-11-09 04:24:34

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

  • 返回实体,但确保它们已初始化。使用 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 with fetch=FetchType.EAGER or use Hibernate.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 some OpenSessionInViewIntercepetor 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文