/** * Creates a Key for a type and an ID value * * @param type the Class of the entity * @param id the ID value * @param <T> the type of the entity * @return the Key */ public <T> Key<T> manualRefToKey(final Class<T> type, final Object id) { return id == null ? null : new Key<T>(type, getCollectionName(type), id); }
<T> Key<T> manualRefToKey(final String collection, final Object id) { return id == null ? null : new Key<T>((Class<? extends T>) getClassFromCollection(collection), collection, id); }
<T> Key<T> createKey(final Class<T> clazz, final Serializable id) { return new Key<T>(clazz, getCollectionName(clazz), id); }
@SuppressWarnings("unchecked") private <T> List<Key<T>> postSaveOperations(final Iterable<T> entities, final Map<Object, DBObject> involvedObjects, final boolean fetchKeys, final String collectionName) { List<Key<T>> keys = new ArrayList<Key<T>>(); for (final T entity : entities) { final DBObject dbObj = involvedObjects.remove(entity); if (fetchKeys) { if (dbObj.get("_id") == null) { throw new MappingException(format("Missing _id after save on %s", entity.getClass().getName())); } mapper.updateKeyAndVersionInfo(this, dbObj, createCache(), entity); keys.add(new Key<T>((Class<? extends T>) entity.getClass(), collectionName, mapper.getId(entity))); } mapper.getMappedClass(entity).callLifecycleMethods(PostPersist.class, entity, dbObj, mapper); } for (Entry<Object, DBObject> entry : involvedObjects.entrySet()) { final Object key = entry.getKey(); mapper.getMappedClass(key).callLifecycleMethods(PostPersist.class, key, entry.getValue(), mapper); } return keys; }
/** * Gets the Key for an entity and a specific collection * * @param entity the entity to process * @param collection the collection to use in the Key rather than the mapped collection as defined on the entity's class * @param <T> the type of the entity * @return the Key */ public <T> Key<T> getKey(final T entity, final String collection) { T unwrapped = entity; if (unwrapped instanceof ProxiedEntityReference) { final ProxiedEntityReference proxy = (ProxiedEntityReference) unwrapped; return (Key<T>) proxy.__getKey(); } unwrapped = ProxyHelper.unwrap(unwrapped); if (unwrapped instanceof Key) { return (Key<T>) unwrapped; } final Object id = getId(unwrapped); final Class<T> aClass = (Class<T>) unwrapped.getClass(); return id == null ? null : new Key<T>(aClass, collection, id); }
/** * Converts a DBRef to a Key * * @param ref the DBRef to convert * @param <T> the type of the referenced entity * @return the Key */ public <T> Key<T> refToKey(final DBRef ref) { return ref == null ? null : new Key<T>((Class<? extends T>) getClassFromCollection(ref.getCollectionName()), ref.getCollectionName(), ref.getId()); }
/** * Gets the Key for an entity * * @param entity the entity to process * @param <T> the type of the entity * @return the Key */ public <T> Key<T> getKey(final T entity) { T unwrapped = entity; if (unwrapped instanceof ProxiedEntityReference) { final ProxiedEntityReference proxy = (ProxiedEntityReference) unwrapped; return (Key<T>) proxy.__getKey(); } unwrapped = ProxyHelper.unwrap(unwrapped); if (unwrapped instanceof Key) { return (Key<T>) unwrapped; } final Object id = getId(unwrapped); final Class<T> aClass = (Class<T>) unwrapped.getClass(); return id == null ? null : new Key<T>(aClass, getCollectionName(aClass), id); }
private Key<?> getKey(final Object entity, final Mapper mapper) { try { if (entity instanceof ProxiedEntityReference) { final ProxiedEntityReference proxy = (ProxiedEntityReference) entity; return proxy.__getKey(); } final MappedClass mappedClass = mapper.getMappedClass(entity); Object id = mappedClass.getIdField().get(entity); if (id == null) { throw new MappingException("@Id field cannot be null!"); } return new Key(mappedClass.getClazz(), mappedClass.getCollectionName(), id); } catch (IllegalAccessException iae) { throw new RuntimeException(iae); } }
<T> Key<T> createKey(final Class<T> clazz, final Object id) { if (id instanceof Serializable) { return createKey(clazz, (Serializable) id); } //TODO: cache the encoders, maybe use the pool version of the buffer that the driver does. final BSONEncoder enc = new BasicBSONEncoder(); return new Key<T>(clazz, getCollectionName(clazz), enc.encode(toDBObject(id))); } }
@Override public Object decode(final Class targetClass, final Object o, final MappedField optionalExtraInfo) { if (o == null) { return null; } if (!(o instanceof DBRef)) { throw new ConverterException(String.format("cannot convert %s to Key because it isn't a DBRef", o.toString())); } DBRef ref = (DBRef) o; MappedField actualType = getActualType(optionalExtraInfo); final Class<?> keyType = actualType != null ? actualType.getConcreteType() : getMapper().getClassFromCollection(ref.getCollectionName()); final Key<?> key = new Key<Object>(keyType, ref.getCollectionName(), ref.getId()); return key; }
@SuppressWarnings("unchecked") private Key<T> convertItem(final DBObject dbObj) { Object id = dbObj.get("_id"); if (id instanceof DBObject) { Class type = mapper.getMappedClass(clazz).getMappedIdField().getType(); id = mapper.fromDBObject(datastore, type, (DBObject) id, mapper.createEntityCache()); } return new Key<T>(clazz, collection, id); } }
@Test public void shouldRejectTypeThatDoesNotMatchKeyKindWhenValueIsAKey() { // given ArrayList<ValidationFailure> validationFailures = new ArrayList<ValidationFailure>(); // when boolean validationApplied = KeyValueTypeValidator.getInstance().apply(String.class, new Key<Number>(Integer.class, "Integer", new ObjectId()), validationFailures); // then assertThat(validationApplied, is(true)); assertThat(validationFailures.size(), is(1)); }
@Test public void shouldAllowTypeThatMatchesKeyKindWhenValueIsAKey() { // given ArrayList<ValidationFailure> validationFailures = new ArrayList<ValidationFailure>(); // when boolean validationApplied = KeyValueTypeValidator.getInstance().apply(Integer.class, new Key<Number>(Integer.class, "Integer", new ObjectId()), validationFailures); // then assertThat(validationApplied, is(true)); assertThat(validationFailures.size(), is(0)); }
@Test public void shouldAllowTypeThatMatchesKeyTypeValue() { // expect MappedClass mappedClass = new MappedClass(SimpleEntity.class, new Mapper()); MappedField mappedField = mappedClass.getMappedField("integer"); assertThat(QueryValidator.isCompatibleForOperator(mappedClass, mappedField, Integer.class, EQUAL, new Key<Number>(Integer.class, "Integer", new ObjectId()), new ArrayList<ValidationFailure>()), is(true)); }
@Test public void shouldNotAllowNonKeyTypeWithKeyValue() { // expect MappedClass mappedClass = new MappedClass(EntityWithListsAndArrays.class, new Mapper()); MappedField mappedField = mappedClass.getMappedField("listOfIntegers"); assertThat(QueryValidator.isCompatibleForOperator(mappedClass, mappedField, SimpleEntity.class, EQUAL, new Key<String>(String.class, "kind", new ObjectId()), new ArrayList<ValidationFailure>()), is(false)); }
@Test public void shouldNotAllowTypeThatDoesNotMatchKeyTypeValue() { // expect MappedClass mappedClass = new MappedClass(SimpleEntity.class, new Mapper()); MappedField mappedField = mappedClass.getMappedField("name"); assertThat(QueryValidator.isCompatibleForOperator(mappedClass, mappedField, String.class, EQUAL, new Key<Number>(Integer.class, "Integer", new ObjectId()), new ArrayList<ValidationFailure>()), is(false)); }
@Override @SuppressWarnings("unchecked") protected Key<T> convertItem(final DBObject dbObj) { Object id = dbObj.get("_id"); if (id instanceof DBObject) { Class type = getMapper().getMappedClass(getClazz()).getMappedIdField().getType(); id = getMapper().fromDBObject(getDatastore(), type, (DBObject) id, getMapper().createEntityCache()); } return new Key<T>(getClazz(), getCollection(), id); } }
@Test public void testInQueryByKey() { checkMinServerVersion(2.5); final HasRef hr = new HasRef(); List<Key<ReferencedEntity>> refs = new ArrayList<Key<ReferencedEntity>>(); for (int x = 0; x < 10; x++) { final ReferencedEntity re = new ReferencedEntity("" + x); getDs().save(re); refs.add(new Key<ReferencedEntity>(ReferencedEntity.class, getMorphia().getMapper().getCollectionName(ReferencedEntity.class), re.getId())); } hr.ref = refs.get(0); getDs().save(hr); Query<HasRef> query = getDs().find(HasRef.class).field("ref").in(refs); try { Assert.assertEquals(1, query.count()); } catch (MongoException e) { LOG.debug("query = " + query); throw e; } }
@Test public void testKeyComparisons() { final User user = new User("Luke Skywalker"); getDs().save(user); final Key<User> k1 = new Key<User>(User.class, "User", user.id); final Key<User> k2 = getDs().getKey(user); Assert.assertTrue(k1.equals(k2)); Assert.assertTrue(k2.equals(k1)); }
@Test public void testWithKeyQuery() { final ContainsPic cpk = new ContainsPic(); final Pic p = new Pic(); cpk.setPic(p); getDs().save(p); getDs().save(cpk); ContainsPic containsPic = getDs().find(ContainsPic.class) .field("pic").equal(new Key<Pic>(Pic.class, "Pic", p.getId())) .find(new FindOptions().limit(1)) .tryNext(); Assert.assertEquals(cpk.getId(), containsPic.getId()); containsPic = getDs().find(ContainsPic.class).field("pic").equal(new Key<Pic>(Pic.class, "Pic", p.getId())) .find(new FindOptions().limit(1)) .tryNext(); Assert.assertEquals(cpk.getId(), containsPic.getId()); } }