1

次のように、データストア (Google アプリ エンジン) 内の 2 つのエンティティをモデル化する 2 つの JPA クラスがあるとします。

@Entity
public class Clazz {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Key classKey;

@Basic
private String classId;

@Basic
private String className;

@ManyToOne
private Subject subject;
    }

@Entity
public class Subject {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Key subjectKey;

@Basic
private String subjectId;

@Basic
private String subjectName;

@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "subject")
private Set<Clazz> classes = new HashSet<Clazz>();
}

したがって、JPA基準を使用して、指定された値と等しいclassIdおよびsubjectIdを持つClazzオブジェクトを取得する方法。このコードを使用しましたが、次のような例外が発生しました。

em = EMF.get().createEntityManager();
        CriteriaBuilder criteriaBuilder = em.getCriteriaBuilder();
        CriteriaQuery<Clazz> criteriaQuery = criteriaBuilder.createQuery(Clazz.class);
        Root<Clazz> root = criteriaQuery.from(Clazz.class);
        List<Predicate> predicates = new ArrayList<Predicate>();

        if (searchObj.getClassId() != null && searchObj.getClassId().length() > 0) {
            Expression<String> classIdExpression = root.get("classId");
            predicates.add(criteriaBuilder.equal(classIdExpression, searchObj.getClassId()));
        }

        if (searchObj.getSubjectId() != null && searchObj.getSubjectId().length() > 0) {
            Join<Clazz, Subject> join = root.join("subject");
            predicates.add(criteriaBuilder.equal(join.get("subjectId"), searchObj.getSubjectId()));
        }

        if (predicates.isEmpty()) {
            criteriaQuery.select(root);
        } else {
            criteriaQuery.select(root).where(predicates.toArray(new Predicate[predicates.size()]));
        }

        TypedQuery<Clazz> query = em.createQuery(criteriaQuery);
        return query.getResultList();

例外:

javax.persistence.PersistenceException: SELECT DN_THIS FROM thesis.filesharing.model.Clazz DN_THIS JOIN DN_THIS.subject WHERE (DN_THIS.classId = '44444') AND (DN_THIS.subject.subjectId = 'IT5834'): Can only reference properties of a sub-object if the sub-object is embedded.
at org.datanucleus.api.jpa.NucleusJPAHelper.getJPAExceptionForNucleusException(NucleusJPAHelper.java:302)
at org.datanucleus.api.jpa.JPAQuery.getResultList(JPAQuery.java:202)
at thesis.filesharing.dao.impl.ClassDAOImpl.countFoundClasses(ClassDAOImpl.java:203)
at thesis.filesharing.bo.impl.ClassBOImpl.countFoundClasses(ClassBOImpl.java:84)
at thesis.filesharing.test.TestController.searchClasses(TestController.java:143)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at com.google.appengine.tools.development.agent.runtime.Runtime.invoke(Runtime.java:115)
at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:219)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:746)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:687)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:925)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:915)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:811)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:796)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:511)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1166)

前もって感謝します

4

3 に答える 3

0

GAE DatastoreデータストアNo-SQL databaseは主にデータ構造に基づいているため、実際にはいくつか読む必要があります。ここには関係がありません(テーブルなし)クラスのみ

@OneToMany..etcはサポートされなくなりました

ウィキペディアから:コンピューティングでは、NoSQL(一般に「SQLだけでなく」[1]と解釈されます)は、広く使用されているリレーショナルデータベース管理システムモデルに準拠していないことで識別される幅広いクラスのデータベース管理システムです。NoSQLデータベースは主にテーブル上に構築されておらず、通常、データ操作にSQLを使用しません。

于 2013-02-24T01:14:18.053 に答える
0

サブオブジェクトが埋め込まれている場合、サブオブジェクトのプロパティのみを参照できます。

十分に明確です。GAE/Datastore は「結合」に簡​​単に対応できません。JPQL の JPA Criteria を使用するかどうかは重要ではありません。それらはデータストアの同じ要件に相当するためです。

于 2013-02-22T19:14:10.683 に答える
0

GAE は条件結合をうまく処理できないため、次のタイプのステートメントを受け入れます。

SELECT f FROM Foo f JOIN f.bar b WHERE b.id = "42"

エイリアスを使用してこの問題のハッキーなソリューションを実装することができましたが、完全に機能します。ただし、この方法の安全性は保証できませんので、自己責任で使用してください。

CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Foo> q = cb.createQuery(Foo.class);
Root<Foo> foo = q.from(Foo.class);

foo.join("bar").alias("b1");  // Comment 1
foo.alias("b1");  // Comment 2
q.select(foo).where(cb.equal(foo.get("id"), "42"));
foo.alias("f1");  // Comment 3

TypedQuery<Foo> query = em.createQuery(q);
List<Foo> foos = query.getResultList();

注意事項:

  • コメント 1: このエイリアスbは、JPQL ステートメントの最初の部分のみを表します。
  • コメント 2: このエイリアスはbin を表しb.idます。
  • コメント 3: このエイリアスはf、JPQL ステートメントの

の結果のステートメントはem.createQuery(q)、上記の JPQL ステートメントと同等です。

于 2014-01-21T00:30:34.373 に答える