JPA/JPQL:単方向木のルート要素を見つける。JPA/JPQL:単方向木のルート要素を見つける
次の問題の名前付きクエリを作成するには、いくつかの助けが必要です。
私はエンティティ(TNode)の定義を次の(簡略化した)ものとし、JPA経由で保存/読み込みできます。 エンティティは単方向であるため、子は親を知らない!
今、すべてのルート要素を取得するために名前付きクエリを作成しようとしています。
私はJPA 2.0(Hibernate)を使用し、インターネットでいくつかのヒントを見つけました。その単方向リンクがサポートされています。
2つのツリーを作成してdbに保存するには、単純なJUnit(4)も付属しています。私はすべての主張を取り除いた。私はJUnitのを実行した場合
、表が期待通りになります。
ID NAME CHILDS_ID
1 A1 (null)
2 A11 1
3 B1 (null)
4 B11 3
私は、同じテーブル内の自己参照を持つように@JoinColumnを追加しました。単純なSQLの場合、問題 は簡単です(WHERE childs_id = null)。しかし、これをJPQLでどのように書く必要がありますか?
お返事ありがとうございます。
ウーヴェ
ここ@Entity
@Table(name = "TNode")
@NamedQueries({ @NamedQuery(name = "getRootNodes", query = "FROM TNode tnode ......."), })
public class TNode implements JPAObject {
@Id
@GeneratedValue
private Integer id;
private String name;
@OneToMany(cascade = { CascadeType.REFRESH, CascadeType.MERGE, CascadeType.REMOVE })
@JoinColumn
private Set<TNode> childs = new HashSet<TNode>();
// JPA only
private TNode() {
}
public TNode(String name) {
this.name = name;
}
public void add(TNode tNode) {
childs.add(tNode);
}
@Override
public Integer getId() {
return id;
}
@Override
public String getName() {
return name;
}
}
簡素化JUnitの
@RunWith(Arquillian.class)
public class TNodeTest {
@Deployment
public static Archive<?> createTestArchive() {
//@formatter:off
Archive<?> archive = ShrinkWrap.create(WebArchive.class, "test.war")
.addPackages(true, DummyInterfaceForTest.class.getPackage())
.addAsLibraries(FindMavenArtifact.find("com.thoughtworks.xstream:xstream:1.4.2"))
.addAsLibraries(FindMavenArtifact.find("xmlpull:xmlpull:1.1.3.1"))
.addAsResource("META-INF/persistence.xml", "META-INF/persistence.xml")
.addAsResource("import.sql", "import.sql")
.addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml");
//@formatter:on
System.out.println(archive.toString(true));
return archive;
}
@Inject
@DAO.DAOType(type = DAO.MODE.STATELESS)
private DAO<JPAObject> dao;
@Test
public void testMutipleRoots() throws Exception {
TNode root;
root = new TNode("A1");
root.add(new TNode("A11"));
dao.saveOrUpdate(root);
root = new TNode("B1");
root.add(new TNode("B11"));
dao.saveOrUpdate(root);
}
}
あなたはこのアソシエーション双方向をしていないことにより、必要以上にそれが難しくなっています。親フィールドは公にアクセス可能である必要はない。しかし、そのようなクエリのために本当に役立つでしょう。 –