@Override public <T> T insert(Object id, T objectToInsert) { if (objectToInsert instanceof PartialUpdate) { doPartialUpdate((PartialUpdate<?>) objectToInsert); return objectToInsert; } if (!(objectToInsert instanceof RedisData)) { RedisConverter converter = adapter.getConverter(); RedisPersistentEntity<?> entity = converter.getMappingContext() .getRequiredPersistentEntity(objectToInsert.getClass()); KeyValuePersistentProperty idProperty = entity.getRequiredIdProperty(); PersistentPropertyAccessor<T> propertyAccessor = entity.getPropertyAccessor(objectToInsert); if (propertyAccessor.getProperty(idProperty) == null) { propertyAccessor.setProperty(idProperty, id); return super.insert(id, propertyAccessor.getBean()); } } return super.insert(id, objectToInsert); }
@Override public <T> T update(Object id, T objectToUpdate) { return super.update(id, objectToUpdate); }
@Override public RedisMappingContext getMappingContext() { return (RedisMappingContext) super.getMappingContext(); }
@Override public void delete(Class<?> type) { Assert.notNull(type, "Type to delete must not be null!"); String keyspace = resolveKeySpace(type); potentiallyPublishEvent(KeyValueEvent.beforeDropKeySpace(keyspace, type)); execute((KeyValueCallback<Void>) adapter -> { adapter.deleteAllOf(keyspace); return null; }); potentiallyPublishEvent(KeyValueEvent.afterDropKeySpace(keyspace, type)); }
@Override public <T> Iterable<T> find(KeyValueQuery<?> query, Class<T> type) { return executeRequired((KeyValueCallback<Iterable<T>>) adapter -> { Iterable<?> result = adapter.find(query, resolveKeySpace(type), type); List<T> filtered = new ArrayList<>(); for (Object candidate : result) { if (typeCheck(type, candidate)) { filtered.add(type.cast(candidate)); } } return filtered; }); }
@Override public <T> Optional<T> findById(Object id, Class<T> type) { Assert.notNull(id, "Id for object to be inserted must not be null!"); Assert.notNull(type, "Type to fetch must not be null!"); String keyspace = resolveKeySpace(type); potentiallyPublishEvent(KeyValueEvent.beforeGet(id, keyspace, type)); T result = execute(adapter -> { Object value = adapter.get(id, keyspace, type); if (value == null || typeCheck(type, value)) { return type.cast(value); } return null; }); potentiallyPublishEvent(KeyValueEvent.afterGet(id, keyspace, type, result)); return Optional.ofNullable(result); }
@Override public <T> T insert(T objectToInsert) { KeyValuePersistentEntity<?, ?> entity = getKeyValuePersistentEntity(objectToInsert); GeneratingIdAccessor generatingIdAccessor = new GeneratingIdAccessor(entity.getPropertyAccessor(objectToInsert), entity.getIdProperty(), identifierGenerator); Object id = generatingIdAccessor.getOrGenerateIdentifier(); return insert(id, objectToInsert); }
@SuppressWarnings("rawtypes") @Override public <T> T update(T objectToUpdate) { KeyValuePersistentEntity<?, ?> entity = getKeyValuePersistentEntity(objectToUpdate); if (!entity.hasIdProperty()) { throw new InvalidDataAccessApiUsageException( String.format("Cannot determine id for type %s", ClassUtils.getUserClass(objectToUpdate))); } return update(entity.getIdentifierAccessor(objectToUpdate).getRequiredIdentifier(), objectToUpdate); }
@SuppressWarnings({ "unchecked", "rawtypes" }) @Override public <T> T delete(T objectToDelete) { Class<T> type = (Class<T>) ClassUtils.getUserClass(objectToDelete); KeyValuePersistentEntity<?, ?> entity = getKeyValuePersistentEntity(objectToDelete); return delete(entity.getIdentifierAccessor(objectToDelete).getIdentifier(), type); }
@Override public long count(KeyValueQuery<?> query, Class<?> type) { return executeRequired(adapter -> adapter.count(query, resolveKeySpace(type))); }
@SuppressWarnings("rawtypes") @Override public <T> Iterable<T> findAll(Sort sort, Class<T> type) { return find(new KeyValueQuery(sort), type); }
@Nullable @Override public <T> T execute(KeyValueCallback<T> action) { Assert.notNull(action, "KeyValueCallback must not be null!"); try { return action.doInKeyValue(this.adapter); } catch (RuntimeException e) { throw resolveExceptionIfPossible(e); } }
/** * Execute {@link KeyValueCallback} and require a non-{@literal null} return value. * * @param action * @param <T> * @return */ protected <T> T executeRequired(KeyValueCallback<T> action) { T result = execute(action); if (result != null) { return result; } throw new IllegalStateException(String.format("KeyValueCallback %s returned null value!", action)); }
@Override public <T> T delete(Object id, Class<T> type) { Assert.notNull(id, "Id for object to be deleted must not be null!"); Assert.notNull(type, "Type to delete must not be null!"); String keyspace = resolveKeySpace(type); potentiallyPublishEvent(KeyValueEvent.beforeDelete(id, keyspace, type)); T result = execute(adapter -> adapter.delete(id, keyspace, type)); potentiallyPublishEvent(KeyValueEvent.afterDelete(id, keyspace, type, result)); return result; }
@Override public <T> Iterable<T> find(KeyValueQuery<?> query, Class<T> type) { return executeRequired((KeyValueCallback<Iterable<T>>) adapter -> { Iterable<?> result = adapter.find(query, resolveKeySpace(type), type); List<T> filtered = new ArrayList<>(); for (Object candidate : result) { if (typeCheck(type, candidate)) { filtered.add(type.cast(candidate)); } } return filtered; }); }
@Override public <T> Optional<T> findById(Object id, Class<T> type) { Assert.notNull(id, "Id for object to be inserted must not be null!"); Assert.notNull(type, "Type to fetch must not be null!"); String keyspace = resolveKeySpace(type); potentiallyPublishEvent(KeyValueEvent.beforeGet(id, keyspace, type)); T result = execute(adapter -> { Object value = adapter.get(id, keyspace, type); if (value == null || typeCheck(type, value)) { return type.cast(value); } return null; }); potentiallyPublishEvent(KeyValueEvent.afterGet(id, keyspace, type, result)); return Optional.ofNullable(result); }
@Override public <T> T insert(T objectToInsert) { KeyValuePersistentEntity<?, ?> entity = getKeyValuePersistentEntity(objectToInsert); GeneratingIdAccessor generatingIdAccessor = new GeneratingIdAccessor(entity.getPropertyAccessor(objectToInsert), entity.getIdProperty(), identifierGenerator); Object id = generatingIdAccessor.getOrGenerateIdentifier(); return insert(id, objectToInsert); }
@SuppressWarnings("rawtypes") @Override public <T> T update(T objectToUpdate) { KeyValuePersistentEntity<?, ?> entity = getKeyValuePersistentEntity(objectToUpdate); if (!entity.hasIdProperty()) { throw new InvalidDataAccessApiUsageException( String.format("Cannot determine id for type %s", ClassUtils.getUserClass(objectToUpdate))); } return update(entity.getIdentifierAccessor(objectToUpdate).getRequiredIdentifier(), objectToUpdate); }
@SuppressWarnings({ "unchecked", "rawtypes" }) @Override public <T> T delete(T objectToDelete) { Class<T> type = (Class<T>) ClassUtils.getUserClass(objectToDelete); KeyValuePersistentEntity<?, ?> entity = getKeyValuePersistentEntity(objectToDelete); return delete(entity.getIdentifierAccessor(objectToDelete).getIdentifier(), type); }
@Override public long count(KeyValueQuery<?> query, Class<?> type) { return executeRequired(adapter -> adapter.count(query, resolveKeySpace(type))); }