Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Embedded JDO Field is not Retrieved by Query

I am using the local-development version of App Engine's JDO implementation. When I query an object that has contains other objects as embedded fields, the embedded fields are returned as null.

For example, lets say this is the main object that I am persisting:

@PersistenceCapable
public class Branch {

    @PrimaryKey
    @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
    private Long id;

    @Persistent
    private String name;

    @Persistent
    private Address address;

            ...
}

and this my embedded object:

@PersistenceCapable(embeddedOnly="true")
public class Address {

    @PrimaryKey
    @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
    private Long id;

    @Persistent
    private String street;

    @Persistent
    private String city;

            ...
}

the following code does not retrieve the embedded object:

    PersistenceManager pm = MyPersistenceManagerFactory.get().getPersistenceManager();

    Branch branch = null;
    try {
        branch = pm.getObjectById(Branch.class, branchId);
    }
    catch (JDOObjectNotFoundException onfe) {
        // not found
    }
    catch (Exception e) {
        // failed
    }
    finally {
        pm.close();
    }

Does anyone have a solution for this? How can I retrieve the Branch object along with its embedded Address field?

like image 320
Chania Avatar asked May 08 '12 06:05

Chania


1 Answers

I had a similar problem and found that embedded fields are not included in the default fetch group. To have the required field loaded you will either have to call the getter for it before closing the persistence manager or set the fetch group to load all fields.

This means the following...

branch = pm.getObjectById(Branch.class, branchId);
pm.close();
branch.getAddress();  // this is null

branch = pm.getObjectById(Branch.class, branchId);
branch.getAddress();  // this is not null
pm.close();
branch.getAddress();  // neither is this

So, you would need to change your code as follows:

Branch branch = null;
try {
    branch = pm.getObjectById(Branch.class, branchId);
    branch.getAddress();
}
catch (JDOObjectNotFoundException onfe) {
    // not found
}
catch (Exception e) {
    // failed
}
finally {
    pm.close();
}

Alternatively, you can set your fetch group to include all fields as follows...

pm.getFetchPlan().setGroup(FetchGroup.ALL);
branch = pm.getObjectById(Branch.class, branchId);
pm.close();
branch.getAddress();  // this is not null
like image 159
Cengiz Avatar answered Oct 19 '22 12:10

Cengiz