2017-11-17 8 views
1

次の問題があります。JPA LazyLoadingコレクションはSOAP経由で転送されました

@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<>(); 
} 

今私が持っている2つのファインダー・メソッド:

  • findAllTeachers():SELECT t from Teacher t
  • findTeacherByIdWithDetails(ロングID)
    私はこのようになりますエンティティを持っています: SELECT t from Teacher t JOIN FETCH t.students s where t.id = :id

私がサーバー側にいる限り、すべてが良好です。 私はwildfly 10アプリケーションサーバーでHibernateを使用しています。

私は2つのSOAP Webサービスメソッドを持っています。すべての教師を返すメソッドと、読み込まれた学生がIDで1人の先生を返すメソッドです。

もちろん、Teacher Entityがすでにデタッチされているため、すべての教師を返すためにwebserviceメソッドを呼び出すと、LazyInitializationExceptionがスローされます。

ここに私の質問があります。このエンティティのDTOを作成する以外の選択肢はありますか? 学生用コレクションに@XMLTransientを設定している場合は、詳細な教師用のWebサービスメソッドを呼び出すときにも隠しています。

この問題で私を助けることができればとてもうれしいです...私はたくさん試しましたが、それはjackson-datatype-hibernateを使ってRESTで動作することが分かりました。しかし、SOAP Webサービスであることが必要です。

答えて

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<>(); 
+0

は、あなたの答えバティストいただきありがとうございますBeauvais、 残念ながら私は例外が発生しました: java.util.Setはインタフェースですが、JAXBはインタフェースを処理できません: -/ So私はラッパークラスを使用しようとしましたが、Setの標準出力のような出力を生成することはできません。 – Johnny90

+0

'XmlAdapter 'を作成してTeacherクラスをWrapperにしようとすると、ここではすべてのクラシックメンバーをコピーし、それを渡す前に上記のようにHibernateのものを特別に扱います。 –

関連する問題