持久性 JDO - 如何使用 JDOQL 查询集合的属性?

发布于 2024-08-23 06:41:21 字数 4935 浏览 14 评论 0原文

我想构建一个应用程序,其中由电子邮件地址标识的用户可以拥有多个应用程序帐户。每个帐户可以有一个或多个用户。我正在尝试将 JDO 存储功能与 Google App Engine Java 结合使用。这是我的尝试:

@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 持久性的理解完全错误吗?

I want to build an application where a user identified by an email address can have several application accounts. Each account can have one or more users. I am trying to use the JDO Storage capabilities with Google App Engine Java. Here is my attempt:

@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
}

When a user logs in, I want to check how many accounts he belongs to. If he or she belongs to more than one then he or she will be presented with a dashboard where he/she can click which account he/she wants to load. This is my code to retrieve a list of app accounts where he/she is registered.

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);
}

But I get the next error:

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)

Any ideas?

Am I getting JDO persistance totally wrong?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

复古式 2024-08-30 06:41:21

AppAccount 类有一个 users 变量,它是一个 ListList 没有直接的 username 属性。

你需要做这样的事情:

@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));

The AppAccount class has a users variable that is a List. The List does not have a username property directly.

You need to do something like this:

@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));
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文