Eclipselink mongoDB本机查询find()不起作用

时间:2012-09-25 16:12:47

标签: java mongodb jpa eclipselink nativequery

我最近正在开发一个带有mongoDB数据库的JAVA项目。因此我决定使用eclipselink 2.4。关于查询,它允许通常的“SQL like”查询,但也(假设)允许本机mongoDB查询。我跟着this tutorial并把一切都搞定了。我能够运行findOne()本机mongoDB查询(queryOne),但我无法运行find()查询(queryAll不起作用)......

  1. 查询queryOne = em.createNativeQuery(“db.ORDER.findOne()”, Order.class);

  2. 查询queryAll = em.createNativeQuery(“db.ORDER.find()”,     Order.class);

  3. 执行查询时出错:

    Exception in thread "main" Local Exception Stack: 
    Exception [EclipseLink-6044] (Eclipse Persistence Services - 2.4.0.v20120608-r11652): org.eclipse.persistence.exceptions.QueryException
    Exception Description: The primary key read from the row [EISMappedRecord(
        value => DBQuery: myTest.ORDER -> undefined)] during the execution of the query was detected to be null.  Primary keys must not contain null.
    Query: ReadAllQuery(referenceClass=Order )
        at org.eclipse.persistence.exceptions.QueryException.nullPrimaryKeyInBuildingObject(QueryException.java:912)
        at org.eclipse.persistence.internal.descriptors.ObjectBuilder.buildObject(ObjectBuilder.java:586)
        at org.eclipse.persistence.internal.descriptors.ObjectBuilder.buildObject(ObjectBuilder.java:562)
        at org.eclipse.persistence.queries.ObjectLevelReadQuery.buildObject(ObjectLevelReadQuery.java:776)
        at org.eclipse.persistence.queries.ReadAllQuery.registerResultInUnitOfWork(ReadAllQuery.java:781)
        at org.eclipse.persistence.queries.ReadAllQuery.executeObjectLevelReadQuery(ReadAllQuery.java:433)
        at org.eclipse.persistence.queries.ObjectLevelReadQuery.executeDatabaseQuery(ObjectLevelReadQuery.java:1149)
        at org.eclipse.persistence.queries.DatabaseQuery.execute(DatabaseQuery.java:852)
        at org.eclipse.persistence.queries.ObjectLevelReadQuery.execute(ObjectLevelReadQuery.java:1108)
        at org.eclipse.persistence.queries.ReadAllQuery.execute(ReadAllQuery.java:392)
        at org.eclipse.persistence.queries.ObjectLevelReadQuery.executeInUnitOfWork(ObjectLevelReadQuery.java:1196)
        at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.internalExecuteQuery(UnitOfWorkImpl.java:2875)
        at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1602)
        at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1584)
        at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1549)
        at org.eclipse.persistence.internal.jpa.QueryImpl.executeReadQuery(QueryImpl.java:231)
        at org.eclipse.persistence.internal.jpa.QueryImpl.getResultList(QueryImpl.java:411)
        at example.Test.testQuery(Test.java:171)
        at example.Test.main(Test.java:54)
    

    使用MongoDB shell执行查询:

    { "_id" : "5061DC17E4B0881F592675A5", "TOTALCOST" : 3187, "SHIPPINGADDRESS" : [     {   "POSTALCODE" : "L5J1H7",    "COUNTRY" : "Canada",   "PROVINCE" : "ON",  "CITY" : "Ottawa",  "STREET" : "17 Jane St." } ], "ORDERLINES" : [  {   "DESCRIPTION" : "machine",  "COST" : 2999,  "LINENUMBER" : 1 },     {   "DESCRIPTION" : "shipping",     "COST" : 129,   "LINENUMBER" : 2 },     {   "DESCRIPTION" : "installation",     "COST" : 59,    "LINENUMBER" : 3 } ], "VERSION" : NumberLong(1), "DESCRIPTION" : "Pinball machine", "CUSTOMER__id" : "5061DC17E4B0881F592675A4", "BILLINGADDRESS" : [   {   "POSTALCODE" : "L5J1H7",    "COUNTRY" : "Canada",   "PROVINCE" : "ON",  "CITY" : "Ottawa",  "STREET" : "17 Jane St." } ] }
    { "_id" : "5061DC17E4B0881F592675A6", "TOTALCOST" : 565, "SHIPPINGADDRESS" : [  {   "POSTALCODE" : "L5J1H7",    "COUNTRY" : "Canada",   "PROVINCE" : "ON",  "CITY" : "Ottawa",  "STREET" : "17 Jane St." } ], "ORDERLINES" : [  {   "DESCRIPTION" : "machine",  "COST" : 500,   "LINENUMBER" : 1 },     {   "DESCRIPTION" : "balls",    "COST" : 5,     "LINENUMBER" : 2 },     {   "DESCRIPTION" : "shipping",     "COST" : 60,    "LINENUMBER" : 3 } ], "VERSION" : NumberLong(1), "DESCRIPTION" : "Foosball", "CUSTOMER__id" : "5061DC17E4B0881F592675A4", "BILLINGADDRESS" : [  {   "POSTALCODE" : "L5J1H8",    "COUNTRY" : "Canada",   "PROVINCE" : "ON",  "CITY" : "Ottawa",  "STREET" : "7 Bank St." } ] }
    { "_id" : "5061DC17E4B0881F592675A8", "TOTALCOST" : 402, "SHIPPINGADDRESS" : [  {   "POSTALCODE" : "L5J1H7",    "COUNTRY" : "Canada",   "PROVINCE" : "ON",  "CITY" : "Ottawa",  "STREET" : "17 Jane St." } ], "ORDERLINES" : [  {   "DESCRIPTION" : "table",    "COST" : 300,   "LINENUMBER" : 1 },     {   "DESCRIPTION" : "balls",    "COST" : 5,     "LINENUMBER" : 2 },     {   "DESCRIPTION" : "rackets",  "COST" : 15,    "LINENUMBER" : 3 },     {   "DESCRIPTION" : "net",  "COST" : 2,     "LINENUMBER" : 4 },     {   "DESCRIPTION" : "shipping",     "COST" : 80,    "LINENUMBER" : 5 } ], "VERSION" : NumberLong(1), "DESCRIPTION" : "Pingpong table", "CUSTOMER__id" : "5061DC17E4B0881F592675A7", "BILLINGADDRESS" : [    {   "POSTALCODE" : "L5J1H8",    "COUNTRY" : "Canada", "PROVINCE" : "ON",    "CITY" : "Ottawa",  "STREET" : "7 Bank St." } ] }
    

    如果你能告诉我如何解决这个或一点办法,我会很感激。

    编辑:JPQL查询可能很有用,我使用一些作为解决方法,但是,我目前无法查询引用ID。例如,如果我有一个带有客户参考的订单(订单只保存客户的ID)和mongoDB查询,我会像taht一样搜索:

    db.ORDER.find({"CUSTOMER__id": "ID"})
    

    我相信JPQL类似的查询会像:

    query = em.createQuery("Select o from Order o where o.customer.id = \"ID\"");
    

    然而,再次......不工作!!错误:

    Exception in thread "main" Local Exception Stack: 
    Exception [EclipseLink-6168] (Eclipse Persistence Services - 2.4.0.v20120608-r11652): org.eclipse.persistence.exceptions.QueryException
    Exception Description: Query failed to prepare, unexpected error occurred: [java.lang.ClassCastException: org.eclipse.persistence.eis.mappings.EISOneToOneMapping cannot be cast to org.eclipse.persistence.mappings.OneToOneMapping].
    Internal Exception: java.lang.ClassCastException: org.eclipse.persistence.eis.mappings.EISOneToOneMapping cannot be cast to org.eclipse.persistence.mappings.OneToOneMapping
    Query: ReadAllQuery(referenceClass=Order jpql="Select o from Order o where o.customer.id = "ID"")
        at org.eclipse.persistence.exceptions.QueryException.prepareFailed(QueryException.java:1572)
        at org.eclipse.persistence.queries.DatabaseQuery.checkPrepare(DatabaseQuery.java:633)
        at org.eclipse.persistence.queries.ObjectLevelReadQuery.checkPrepare(ObjectLevelReadQuery.java:882)
        at org.eclipse.persistence.queries.DatabaseQuery.execute(DatabaseQuery.java:838)
        at org.eclipse.persistence.queries.ObjectLevelReadQuery.execute(ObjectLevelReadQuery.java:1108)
        at org.eclipse.persistence.queries.ReadAllQuery.execute(ReadAllQuery.java:392)
        at org.eclipse.persistence.queries.ObjectLevelReadQuery.executeInUnitOfWork(ObjectLevelReadQuery.java:1196)
        at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.internalExecuteQuery(UnitOfWorkImpl.java:2875)
        at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1602)
        at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1584)
        at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1549)
        at org.eclipse.persistence.internal.jpa.QueryImpl.executeReadQuery(QueryImpl.java:231)
        at org.eclipse.persistence.internal.jpa.QueryImpl.getResultList(QueryImpl.java:411)
        at example.Test.testQuery(Test.java:175)
        at example.Test.main(Test.java:55)
    Caused by: java.lang.ClassCastException: org.eclipse.persistence.eis.mappings.EISOneToOneMapping cannot be cast to org.eclipse.persistence.mappings.OneToOneMapping
        at org.eclipse.persistence.internal.expressions.RelationExpression.checkForeignKeyJoinOptimization(RelationExpression.java:512)
        at org.eclipse.persistence.internal.expressions.RelationExpression.normalize(RelationExpression.java:535)
        at org.eclipse.persistence.internal.expressions.SQLSelectStatement.normalize(SQLSelectStatement.java:1365)
        at org.eclipse.persistence.internal.queries.ExpressionQueryMechanism.buildNormalSelectStatement(ExpressionQueryMechanism.java:543)
        at org.eclipse.persistence.internal.queries.ExpressionQueryMechanism.prepareSelectAllRows(ExpressionQueryMechanism.java:1675)
        at org.eclipse.persistence.queries.ReadAllQuery.prepareSelectAllRows(ReadAllQuery.java:719)
        at org.eclipse.persistence.queries.ReadAllQuery.prepare(ReadAllQuery.java:656)
        at org.eclipse.persistence.queries.DatabaseQuery.checkPrepare(DatabaseQuery.java:614)
        ... 13 more
    

    由于

2 个答案:

答案 0 :(得分:0)

它似乎试图获取一个主键为null的对象。此外,记录是A5, A6 and A8.如果它们按顺序创建,看起来A7会搞砸吗?

是否可以删除ORDER文档并再次运行测试(插入和获取)?

答案 1 :(得分:0)

我不认为find()与本地MongoDB API的findOne()相同。

在没有类的情况下执行本机查询时会发生什么?

即。 查询queryAll = em.createNativeQuery(“db.ORDER.find()”); queryAll.getResultList();

你得到了什么?

我不认为直接支持本机find()(但您可以在大多数查询中使用JPQL)。请记录一个错误,应该有一些方法让它工作。