2013-02-22 45 views
1

假設我有2 JPA類哪種模式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>(); 
} 

那麼,如何讓具有的classid clazz中的對象和subjectId等於使用JPA標準的給定值。我用這個代碼,但有這樣的例外:

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) 

在此先感謝

回答

0

只能一個子對象的引用屬性,如果子對象是嵌入式的 。

非常明確。 GAE/Datastore無法輕鬆應對「加入」。無論是使用JPQL的JPA標準是不相關的,因爲它們等同於數據存儲上基於No-SQL database這主要是基於數據結構相同的要求

0

其實你應該閱讀一些有關GAE Datastore,因爲數據存儲沒有任何關係這裏(無表)只有類

@ OneToMany..etc不支持任何更

維基百科在COMPU NoSQL(通常被解釋爲「不僅是SQL」[1])是通過不遵守廣泛使用的關係數據庫管理系統模型而確定的廣泛類別的數據庫管理系統。 NoSQL數據庫不是主要建立在表上,並且通常不使用SQL進行數據操作。

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:此別名代表在JPQL語句只第一b
  • 評論2:這個別名代表bb.id
  • 註釋3:此別名代表在JPQL語句

em.createQuery(q)所得聲明是等效於上面的JPQL語句f

相關問題