Java JPA懒散加载通过SOAP传输的集合

Java JPA懒散加载通过SOAP传输的集合,java,hibernate,soap,lazy-loading,Java,Hibernate,Soap,Lazy Loading,我有以下问题。 我有一个实体,看起来像这样: @Entity @XmlRootElement @XmlAccessorType(XmlAccessType.FIELD) public class Teacher{ @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @OneToMany(fetch = FetchType.LAZY, cascade = CascadeTy

我有以下问题。
我有一个实体,看起来像这样:

@Entity
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Teacher{

  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private Long id;      

  @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
  @JoinColumn(name = "teacherId", referencedColumnName = "id", nullable = false)
  private final Set<Student> students = new HashSet<>();
}
@实体
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
公共班主任{
@身份证
@GeneratedValue(策略=GenerationType.IDENTITY)
私人长id;
@OneToMany(fetch=FetchType.LAZY,cascade=CascadeType.ALL,orphan=true)
@JoinColumn(name=“teacherId”,referencedColumnName=“id”,nullable=false)
私有最终集学生=新HashSet();
}
现在我有两种查找方法:

  • FindAllTech():
    从教师t中选择t
  • findTeacherByIdWithDetails(长id):
    从教师中选择t,加入获取t.students,其中t.id=:id
只要我在服务器端,一切都很好。 我正在wildfly 10应用服务器上使用Hibernate。

我有两个SOAP Web服务方法,一个用于返回所有教师,另一个用于通过id返回一名教师,并加载学生

当然,当我调用返回所有教师的webservice方法时,会抛出LazyInitializationException,因为教师实体已经分离

现在是我的问题。除了为该实体创建DTO之外,还有其他选项吗? 如果我为students集合设置
@xmltransive
,那么在调用详细教师的webservice方法时,我也会隐藏它


如果你能帮我解决这个问题就太好了。。。我尝试了很多,我知道通过使用jackson数据类型hibernate,它可以与REST一起工作。但它必须是一个SOAP Web服务。

您可以尝试使用一个可以处理未初始化的Hibernate集合的自定义服务,例如:

public class StudentSetXmlAdapter extends XmlAdapter<Set<Student>, Set<Student>> {

    @Override
    public Set<Student> marshal(Set<Student> value) throws Exception {
        //PersistentSet is the Hibernate's implementation of Set that handle Lazy-loading etc...
        if (value instanceof PersistentSet) {
            PersistentSet hibernateCollection = (PersistentSet) value;

            //If the data were already loaded you return the collection 
            return hibernateCollection.wasInitialized() ? value : null;
        } else
            return value;
    }

    @Override
    public Set<Student> unmarshal(Set value) throws Exception {
        return value;
    }

}

感谢您的回答Baptiste Beauvais,不幸的是现在我得到了一个例外:java.util.Set是一个接口,JAXB无法处理接口:-/因此我尝试使用包装器类,但无法生成类似于Sets标准输出的输出…您可以尝试通过创建
XmlAdapter
将教师类作为包装器,您只需复制所有经典成员,并像前面一样专门处理Hibernate的成员通过它。
@OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
@JoinColumn(name = "teacherId", referencedColumnName = "id", nullable = false)
@XmlJavaTypeAdapter(StudentSetXmlAdapter.class)
private final Set<Student> students = new HashSet<>();