2010-03-03 2 views
4

전자 메일 주소로 식별 된 사용자가 여러 응용 프로그램 계정을 가질 수있는 응용 프로그램을 만들고 싶습니다. 각 계정에는 하나 이상의 사용자가있을 수 있습니다. Google App Engine Java에서 JDO 저장소 기능을 사용하려고합니다. 내 시도는 다음과 같습니다.Persistance JDO - JDOQL을 사용하여 컬렉션의 속성을 쿼리하는 방법은 무엇입니까?

@PersistenceCapable 
@Inheritance(strategy = InheritanceStrategy.NEW_TABLE) 
public class AppAccount { 
    @PrimaryKey 
    @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY) 
    private Long id; 

    @Persistent 
    private String companyName; 

    @Persistent 
    List<Invoices> invoices = new ArrayList<Invoices>(); 

    @Persistent 
    List<AppUser> users = new ArrayList<AppUser>(); 

    // Getter Setters and Other Fields 
} 

@PersistenceCapable 
@EmbeddedOnly 
public class AppUser { 

    @Persistent 
    private String username; 

    @Persistent 
    private String firstName; 

    @Persistent 
    private String lastName; 

    // Getter Setters and Other Fields 
} 

사용자가 로그인하면 해당 사용자가 속한 계정 수를 확인하려고합니다. 그 또는 그녀가 둘 이상에 속하면 그 또는 그녀는 그/그녀가로드하고 싶은 계정을 클릭 할 수있는 대시 보드가 제공 될 것입니다. 이 코드는 등록 된 앱 계정 목록을 검색하는 코드입니다.

public static List<AppAccount> getUserAppAccounts(String username) { 
    PersistenceManager pm = JdoUtil.getPm(); 
    Query q = pm.newQuery(AppAccount.class); 
    q.setFilter("users.username == usernameParam"); 
    q.declareParameters("String usernameParam"); 
    return (List<AppAccount>) q.execute(username); 
} 

하지만 다음 오류 얻을 :

SELECT FROM invoices.server.AppAccount WHERE users.username == usernameParam PARAMETERS String usernameParam: Encountered a variable expression that isn't part of a join. Maybe you're referencing a non-existent field of an embedded class. 
org.datanucleus.store.appengine.FatalNucleusUserException: SELECT FROM com.softamo.pelicamo.invoices.server.AppAccount WHERE users.username == usernameParam PARAMETERS String usernameParam: Encountered a variable expression that isn't part of a join. Maybe you're referencing a non-existent field of an embedded class. 
    at org.datanucleus.store.appengine.query.DatastoreQuery.getJoinClassMetaData(DatastoreQuery.java:1154) 
    at org.datanucleus.store.appengine.query.DatastoreQuery.addLeftPrimaryExpression(DatastoreQuery.java:1066) 
    at org.datanucleus.store.appengine.query.DatastoreQuery.addExpression(DatastoreQuery.java:846) 
    at org.datanucleus.store.appengine.query.DatastoreQuery.addFilters(DatastoreQuery.java:807) 
    at org.datanucleus.store.appengine.query.DatastoreQuery.performExecute(DatastoreQuery.java:226) 
    at org.datanucleus.store.appengine.query.JDOQLQuery.performExecute(JDOQLQuery.java:85) 
    at org.datanucleus.store.query.Query.executeQuery(Query.java:1489) 
    at org.datanucleus.store.query.Query.executeWithArray(Query.java:1371) 
    at org.datanucleus.jdo.JDOQuery.execute(JDOQuery.java:243) 
    at com.softamo.pelicamo.invoices.server.Store.getUserAppAccounts(Store.java:82) 
    at com.softamo.pelicamo.invoices.test.server.StoreTest.testgetUserAppAccounts(StoreTest.java:39) 
    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 org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44) 
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15) 
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41) 
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20) 
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28) 
    at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31) 
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:76) 
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50) 
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193) 
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52) 
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191) 
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42) 
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184) 
    at org.junit.runners.ParentRunner.run(ParentRunner.java:236) 
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:46) 
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197) 

어떤 아이디어?

전 JDO 지속성이 완전히 잘못 되었습니까?

답변

5

AppAccount 클래스의 변수는 이고 List입니다. List에는 사용자 이름 속성이 직접 없습니다.

은 당신이 뭔가를 할 필요가 :

@PersistenceCapable 
@EmbeddedOnly 
public class AppUser { 

    @Persistent 
    private String username; 

    @Persistent 
    private String firstName; 

    @Persistent 
    private String lastName; 

    //override equals method for List .contains 
    @Override 
    public boolean equals(AppUser au) { 
     return au.getUsername().equals(this.username); 
    } 

    // Getter Setters and Other Fields 
} 

Query q = pm.newQuery(AppAccount.class); 
//the : denotes an implicit variable will be passed to query execute method 
q.setFilter("users.contains(:username)"); 
//create a new AppUser with the username you want to check, this query will find the AppAccount with any AppUser with the same username, because the .equals method of AppUser has been overridden to return true based on the username member variable 
List<AppAccount> results = (List<AppAccount>)query.execute(new AppUser(username)); 
+0

어떻게이 일 때이 클래스 APPUSER에 대한 1, 인수 생성자가 없다? 감사합니다 :) – jmort253

+0

Google은 컬렉션 내용을 필터링하기 위해 [일부 문서] (https://developers.google.com/appengine/docs/java/datastore/jdo/queries#Filters)를 제공합니다. jmort253 : AppUser의 생성자 매개 변수가 무엇인지는 중요하지 않습니다. 중요한 것은 [query.execute()] (http://db.apache.org/jdo/api30/apidocs/javax/jdo/Query#execute())에 제공된 "username"필터 매개 변수가 equals() AppUser에 결과 AppAccount 값이 사용자 컬렉션에 있어야합니다. Finbarr이 .equals() 메소드를 오버라이드하여 여기에서 수행 한 작업입니다. – dmiller309

관련 문제