Reputation: 909
I have a situation - in my EquipmentType class I have a list of equipment checkouts
List<Key<EquipmentCheckout>> field
after reading the answer to this question: Objectify Relationships: One-to-Many, Can I do this efficiently? - it seems as the more efficient way to do this is to create a class called EquipmentCheckouts which would look something like the following:
class EquipmentCheckouts
@Id
Long id
@Parent
EquipmentType equipmentType
@Indexed
List<EquipmentCheckout> equipmentCheckouts
now - here's what I'm wondering - I'm using RequestFactory and I believe the RequestFactory has to have a find(Long id) method. From what I understand in order to retrieve an EquipmentCheckouts object with an EquipmentType parent you would have to do something along the lines of the following:
Key<EquipmentType> key = ObjectifyService.factory().getKey(equipmentType)
return ofy.get(new Key<EquipmentCheckouts>(key, EquipmentCheckouts.class, id))
So, if you couldn't have the EquipmentType in the find(Long id) method how are you supposed to do this?
For everything else in my system I have a Business parent which is stored in the logged in users session, that way when I go to retrieve everything I authenticate the user then key the business to find whatever it is. I feel as if there's something i'm not understanding about using @Parent in Objectify correctly.
Upvotes: 0
Views: 1014
Reputation: 290
Ruslan answer is spot-on. It solves the issue for Entities with Parents and still work for root-entities.
I copy here an updated version of the locator code using Objectify 4 in case it is useful for anyone passing by.
@Override
public EntityObject find(Class<? extends EntityObject> clazz, String id) {
Key<EntityObject> key = Key.create(id);
EntityObject ob = ofy().load().key(key).now();
return ob;
}
@Override
public String getId(EntityObject domainObject) {
if (domainObject.getId() != null)
{
Key<EntityObject> key = Key.create(domainObject);
return key.getString();
} else
return null;
}
Upvotes: 0
Reputation: 30095
You need to implement your own Locator that would support entities with parent. As you correctly noted you can't just use long ID because it doesn't have Key of a parent. I solved this issue by implementing Locator that uses composite string key that contains full path to the object.
The important thing here is that composite key is used only for RPC. Your entities still use long ID and don't have to be modified.
Here is code snippet:
public class PojoLocator extends Locator<DatastoreObject, String>
{
@Override
public DatastoreObject find(Class<? extends DatastoreObject> clazz, String id)
{
Key<DatastoreObject> key = Key.create(id);
return ofy.load(key);
}
@Override
public String getId(DatastoreObject domainObject)
{
if (domainObject.getId() != null)
{
Key<DatastoreObject> key = ofy.fact().getKey(domainObject);
return key.getString();
} else
return null;
}
}
You can see full version of my locator here.
Upvotes: 2
Reputation: 80330
It does not have to be only Long
in RequestFactory interface. As docs say :
Built-in value types: BigDecimal, BigInteger, Boolean, Byte, Enum, Character, Date, Double, Float, Integer, Long, Short, String, Void
Custom value types: any subclass of ValueProxy
Entity types: any subclass of EntityProxy
Collections: List<T> or Set<T>, where T is one of the above value or entity types
So you can have two longs: find(Long, Long)
. One for the parent and the er for the enntity.
Upvotes: 0