私のJboss7JavaEE 6 Webアプリケーションでは、次のような単純な「カテゴリ」エンティティのツリー構造を管理する必要があります。
@Entity
@Table(name="categorie")
@NamedQueries({
@NamedQuery(name="selezionaTutti", query="select c from Categoria c left join fetch c.children left join fetch c.parent")
})
public class Categoria implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@NotNull
private String nome;
@OneToMany(cascade=CascadeType.ALL,fetch=FetchType.EAGER)
@JoinColumn(name = "parent_id")
private List<Categoria> children = new LinkedList<Categoria>();
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name = "parent_id",insertable=false,updatable=false)
private Categoria parent;
... //various getter, setter, and so on
}
名前付きクエリは、最初に一度にすべての(小さな)ツリーをロードし、その後、永続コンテキストにとどまります。
次に、ツリーを「探索」したいので、ルートノードを取得して、この関数に渡します。
private List<Categoria> getAlberoCategorie(Categoria root, int profondita) {
List<Categoria> tmpList = new ArrayList<Categoria>();
root.setProfondita(profondita);
if ( root.getParent() != null ) {
tmpList.add(root);
}
if (!root.getChildren().isEmpty()) {
profondita++;
for (Categoria figlia : root.getChildren()) {
tmpList.addAll(getAlberoCategorie(figlia,profondita)); // this line generates the stack overflow!!!
}
}
return tmpList;
}
例外の正確なスタックトレースは次のとおりです。
java.lang.StackOverflowError org.hibernate.collection.internal.AbstractPersistentCollection.read(AbstractPersistentCollection.java:112)org.hibernate.collection.internal.AbstractPersistentCollection.readSize(AbstractPersistentCollection.java:137)org.hibernate.collection.internal.PersistentBag .isEmpty(PersistentBag.java:249)it.trew.data.CategoriaFacade.getAlberoCategorie(CategoriaFacade.java:59)
私のローカルマシンでは、すべてが実際に正常に動作します。小さなテストサーバーでは、カテゴリを読み取るときにクラッシュします。
どうすれば機能を改善できますか?