Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: Issue #96: NullPointerException for findAllByOrderByProperty queries #121

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -28,16 +28,16 @@ public interface Query<T> {
* @throws IllegalStateException if called for a Java
* Persistence query language UPDATE or DELETE statement
*/
public List<T> getResultList();
List<T> getResultList();

/**
* Execute a SELECT query that returns a single result.
* @return the result
*/
public T getSingleResult();
T getSingleResult();


public void setScanEnabled(boolean scanEnabled);
public void setScanCountEnabled(boolean scanCountEnabled);
void setScanEnabled(boolean scanEnabled);
void setScanCountEnabled(boolean scanCountEnabled);

}
Expand Up @@ -25,6 +25,10 @@
*/
public interface DynamoDBQueryCriteria<T, ID> {

default DynamoDBQueryCriteria<T, ID> NULL() {
return new NullDynamoDBQueryCriteria();
}

DynamoDBQueryCriteria<T, ID> withSingleValueCriteria(String propertyName, ComparisonOperator comparisonOperator,
Object value, Class<?> type);

Expand Down
@@ -0,0 +1,96 @@
package org.socialsignin.spring.data.dynamodb.repository.query;

import com.amazonaws.services.dynamodbv2.model.ComparisonOperator;
import org.socialsignin.spring.data.dynamodb.core.DynamoDBOperations;
import org.socialsignin.spring.data.dynamodb.query.Query;
import org.springframework.data.domain.Sort;

import java.util.Collections;
import java.util.List;

public class NullDynamoDBQueryCriteria<T, ID> implements DynamoDBQueryCriteria<T, ID> {

private static final Query<Object> EMPTY_QUERY_RESULT = new Query<Object>() {
@Override
public List<Object> getResultList() {
return Collections.emptyList();
}

@Override
public Object getSingleResult() {
return null;
}

@Override
public void setScanEnabled(boolean scanEnabled) {
}

@Override
public void setScanCountEnabled(boolean scanCountEnabled) {
}
};

private static final Query<Long> ZERO_QUERY_RESULT = new Query<Long>() {
private final Long ZERO = Long.valueOf(0L);
private final List<Long> ZERO_LIST = Collections.singletonList(ZERO);

@Override
public List<Long> getResultList() {
return ZERO_LIST;
}

@Override
public Long getSingleResult() {
return ZERO;
}

@Override
public void setScanEnabled(boolean scanEnabled) {
}

@Override
public void setScanCountEnabled(boolean scanCountEnabled) {
}
};


@Override
public DynamoDBQueryCriteria<T, ID> withSingleValueCriteria(String propertyName, ComparisonOperator comparisonOperator, Object value, Class<?> type) {
return this;
}

@Override
public DynamoDBQueryCriteria<T, ID> withNoValuedCriteria(String segment, ComparisonOperator null1) {
return this;
}

@Override
public DynamoDBQueryCriteria<T, ID> withPropertyEquals(String segment, Object next, Class<?> type) {
return this;
}

@Override
public DynamoDBQueryCriteria<T, ID> withPropertyIn(String segment, Iterable<?> o, Class<?> type) {
return this;
}

@Override
public DynamoDBQueryCriteria<T, ID> withPropertyBetween(String segment, Object value1, Object value2, Class<?> type) {
return this;
}

@Override
public DynamoDBQueryCriteria<T, ID> withSort(Sort sort) {
return this;
}

@Override
public Query<T> buildQuery(DynamoDBOperations dynamoDBOperations) {
return (Query<T>)EMPTY_QUERY_RESULT;
}

@Override
public Query<Long> buildCountQuery(DynamoDBOperations dynamoDBOperations, boolean pageQuery) {
return ZERO_QUERY_RESULT;
}
}
@@ -0,0 +1,63 @@
/**
* Copyright © 2013 spring-data-dynamodb (https://github.com/derjust/spring-data-dynamodb)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.socialsignin.spring.data.dynamodb.domain.sample;


import com.amazonaws.services.dynamodbv2.AmazonDynamoDB;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.socialsignin.spring.data.dynamodb.repository.config.EnableDynamoDBRepositories;
import org.socialsignin.spring.data.dynamodb.utils.DynamoDBLocalResource;
import org.socialsignin.spring.data.dynamodb.utils.DynamoDBResource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import java.time.Instant;
import java.util.List;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {DynamoDBLocalResource.class, RepositoryFindTest.TestAppConfig.class})
public class RepositoryFindTest {

@Configuration
@EnableDynamoDBRepositories(basePackages = "org.socialsignin.spring.data.dynamodb.domain.sample")
public static class TestAppConfig {
}

@Autowired
private AmazonDynamoDB ddb;
@Autowired
private UserRepository userRepository;

@Before
public void setUp() {
DynamoDBLocalResource.createTable(ddb, User.class);
}

@Test
public void testFindAll() {
//List<User> actual1 = userRepository.findByLeaveDate(Instant.now());

List<User> actual3 = userRepository.findByNameOrderByNameAsc("x");

// List<User> actual = userRepository.findAllByOrderByName();
}
}


Expand Up @@ -30,6 +30,12 @@ public interface UserRepository extends Repository<User, String> {
@EnableScan
List<User> findByLeaveDate(Instant leaveDate);

@EnableScan
List<User> findByNameOrderByNameAsc(String name);

@EnableScan
List<User> findAll();

@EnableScan
Optional<User> findByName(String name);

Expand Down
Expand Up @@ -25,12 +25,16 @@
import com.amazonaws.services.dynamodbv2.model.ProvisionedThroughput;
import com.amazonaws.services.dynamodbv2.model.ScalarAttributeType;
import org.junit.rules.ExternalResource;
import org.socialsignin.spring.data.dynamodb.repository.support.DynamoDBEntityInformation;
import org.socialsignin.spring.data.dynamodb.repository.support.DynamoDBEntityMetadataSupport;
import org.socialsignin.spring.data.dynamodb.repository.support.DynamoDBIdIsHashAndRangeKeyEntityInformation;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.swing.text.html.Option;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

@Configuration
public class DynamoDBLocalResource extends ExternalResource {
Expand All @@ -43,27 +47,31 @@ public AmazonDynamoDB amazonDynamoDB() {
return ddb;
}

public CreateTableResult createTable(Class<?> domainType) {
public static CreateTableResult createTable(AmazonDynamoDB ddb, Class<?> domainType) {
DynamoDBEntityMetadataSupport support = new DynamoDBEntityMetadataSupport(domainType);
DynamoDBEntityInformation entityInfo = support.getEntityInformation();

String tableName = support.getDynamoDBTableName();
String hashKey = support.getHashKeyPropertyName();
String rangeKey = support.getHashKeyPropertyName();
String tableName = entityInfo.getDynamoDBTableName();
String hashKey = entityInfo.getHashKeyPropertyName();
Optional<String> rangeKey = Optional.empty();
if (entityInfo instanceof DynamoDBIdIsHashAndRangeKeyEntityInformation) {
rangeKey = Optional.of(((DynamoDBIdIsHashAndRangeKeyEntityInformation)entityInfo).getRangeKeyPropertyName());
}

return createTable(tableName, hashKey, rangeKey);
return createTable(ddb, tableName, hashKey, rangeKey);
}

private CreateTableResult createTable(String tableName, String hashKeyName, String rangeKeyName) {
private static CreateTableResult createTable(AmazonDynamoDB ddb, String tableName, String hashKeyName, Optional<String> rangeKeyName) {
List<AttributeDefinition> attributeDefinitions = new ArrayList<>();
attributeDefinitions.add(new AttributeDefinition(hashKeyName, ScalarAttributeType.S));

List<KeySchemaElement> ks = new ArrayList<>();
ks.add(new KeySchemaElement(hashKeyName, KeyType.HASH));

if (rangeKeyName != null) {
attributeDefinitions.add(new AttributeDefinition(rangeKeyName, ScalarAttributeType.S));
if (rangeKeyName.isPresent()) {
attributeDefinitions.add(new AttributeDefinition(rangeKeyName.get(), ScalarAttributeType.S));

ks.add(new KeySchemaElement(rangeKeyName, KeyType.RANGE));
ks.add(new KeySchemaElement(rangeKeyName.get(), KeyType.RANGE));
}

ProvisionedThroughput provisionedthroughput = new ProvisionedThroughput(10L, 10L);
Expand Down