我遇到了以下问题 我有一个看起来像这样的实体:
@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<>();
}
现在我有两种取景方法:
SELECT t from Teacher t
SELECT t from Teacher t JOIN FETCH t.students s where t.id = :id
只要我在服务器端,一切都很好。
我在wildfly 10应用服务器上使用Hibernate。
我有两个SOAP webservice方法,一个返回所有教师的方法和一个方法,用于在学生加载的情况下通过id返回一个教师。
当然,当我调用webservice方法返回所有教师时,抛出了LazyInitializationException,因为教师实体已经分离。
现在这是我的问题。除了为此实体创建DTO之外,还有其他选择吗?
如果我为学生集合设置@XMLTransient
,那么当我为详细教师调用webservice方法时,我也会隐藏它。
如果你可以帮我解决这个问题,那将是非常好的...我尝试了很多,我知道它可以通过使用jackson-datatype-hibernate与REST一起工作。但它必须是SOAP Web服务。
答案 0 :(得分:0)
您可以尝试使用可以处理非初始化Hibernate集合的自定义XmlAdapter,例如:
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;
}
}
并在您的字段上添加注释@XmlJavaTyAdapter
:
@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<>();