AWS - DynamoDB - CRUD方法无法正常工作

时间:2018-01-04 14:38:20

标签: java amazon-web-services amazon-dynamodb converter objectmapper

我真的需要你的帮助,我正在尝试创建简单的厨房管理应用程序。我决定将AWS与DynamoDB一起使用,我坚持使用CRUD方法:添加和删除方法似乎工作正常,但我在编辑数据库记录时遇到很大问题。

日志文件中的错误消息:

"Can not deserialize instance of java.util.ArrayList out of START_OBJECT token "

这就是我的模型类的样子:

@DynamoDBTable(tableName = "product")
public class Product extends Request {

/**
 * Id of kitchen content
 */
private String id;
/**
 * Name of product
 */
private String name;

/**
 * Calories in 100g
 */
private Integer calories;

/**
 * Fat in 100g
 */
private Double fat;

/**
 * Total carbo in 100g
 */
private Double carbo;

/**
 * Total Protein in 100g
 */
private Double protein;

/**
 * Labels of product for example gluten fee product
 */
private List<ProductKind> productKinds;

/**
 * Author of content.
 */
private Author author;

/**
 * Address of content image.
 */
private Media media;

private Boolean approved;

@DynamoDBHashKey(attributeName = "id")
@DynamoDBAutoGeneratedKey
public String getId() {
    return id;
}

public void setId(String id) {
    this.id = id;
}

@DynamoDBAttribute(attributeName = "Name")
public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

@DynamoDBAttribute(attributeName = "Calories")
public Integer getCalories() {
    return calories;
}

public void setCalories(Integer calories) {
    this.calories = calories;
}

@DynamoDBAttribute(attributeName = "Fat")
public Double getFat() {
    return fat;
}

public void setFat(Double fat) {
    this.fat = fat;
}

@DynamoDBAttribute(attributeName = "Carbo")
public Double getCarbo() {
    return carbo;
}

public void setCarbo(Double carbo) {
    this.carbo = carbo;
}

@DynamoDBAttribute(attributeName = "Protein")
public Double getProtein() {
    return protein;
}

public void setProtein(Double protein) {
    this.protein = protein;
}

@DynamoDBTypeConverted(converter = EnumConverter.class)
@DynamoDBAttribute(attributeName = "ProductKinds")
public List<ProductKind> getProductKinds() {
    return productKinds;
}

public void setProductKinds(List<ProductKind> productKinds) {
    this.productKinds = productKinds;
}

@DynamoDBTypeConverted(converter = ObjectConverter.class)
@DynamoDBAttribute(attributeName = "Author")
public Author getAuthor() {
    return author;
}

public void setAuthor(Author author) {
    this.author = author;
}

@DynamoDBTypeConverted(converter = ObjectConverter.class)
@DynamoDBAttribute(attributeName = "Media")
public Media getMedia() {
    return media;
}

public void setMedia(Media media) {
    this.media = media;
}

@DynamoDBAttribute(attributeName = "Approved")
public Boolean getApproved() {
    return approved;
}

public void setApproved(Boolean approved) {
    this.approved = approved;
}


@Override
public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;

    Product product = (Product) o;

    if (name != null ? !name.equals(product.name) : product.name != null) return false;
    if (calories != null ? !calories.equals(product.calories) : product.calories != null) return false;
    if (fat != null ? !fat.equals(product.fat) : product.fat != null) return false;
    if (carbo != null ? !carbo.equals(product.carbo) : product.carbo != null) return false;
    if (protein != null ? !protein.equals(product.protein) : product.protein != null) return false;
    if (productKinds != null ? !productKinds.equals(product.productKinds) : product.productKinds != null)
        return false;
    if (author != null ? !author.equals(product.author) : product.author != null) return false;
    if (media != null ? !media.equals(product.media) : product.media != null) return false;
    return approved != null ? approved.equals(product.approved) : product.approved == null;
}

@Override
public int hashCode() {
    int result = id != null ? id.hashCode() : 0;
    result = 31 * result + (name != null ? name.hashCode() : 0);
    result = 31 * result + (calories != null ? calories.hashCode() : 0);
    result = 31 * result + (fat != null ? fat.hashCode() : 0);
    result = 31 * result + (carbo != null ? carbo.hashCode() : 0);
    result = 31 * result + (protein != null ? protein.hashCode() : 0);
    result = 31 * result + (productKinds != null ? productKinds.hashCode() : 0);
    result = 31 * result + (author != null ? author.hashCode() : 0);
    result = 31 * result + (media != null ? media.hashCode() : 0);
    result = 31 * result + (approved != null ? approved.hashCode() : 0);
    return result;
}


@Override
public String toString() {
    return "Product{" +
            "id='" + id + '\'' +
            ", name='" + name + '\'' +
            ", calories=" + calories +
            ", fat=" + fat +
            ", carbo=" + carbo +
            ", protein=" + protein +
            ", productKinds=" + productKinds +
            ", author=" + author +
            ", media=" + media +
            ", approved=" + approved +
            '}';
}

这就是我的服务方法的样子:

public class KitchenService {

public KitchenService(DatabaseController databaseController, LambdaLogger logger) {
    this.databaseController = databaseController;
    this.logger = logger;
}


private DatabaseController databaseController;
private LambdaLogger logger;

public Product addProduct(Product content) {

    databaseController.saveTest(content);
    logger.log("Product created");

    return content;

}

public Product editProduct(Product product) {
    Product databaseProduct = databaseController.get(Product.class, product.getId());
    if (databaseProduct != null) {
        logger.log("Database product exist: " + databaseProduct.toString());
    }
    if (product.getId() != null && product.getId().isEmpty()) databaseController.save(product);

    databaseController.save(databaseProduct);

    logger.log("Product updated");

    return databaseProduct;
}


public void deleteProduct(Product product) {
    Product databaseProduct = databaseController.get(Product.class, product.getId());
    databaseController.deleteProductFromDB(databaseProduct);

    logger.log("Item deleted");
}

当然,你需要看看dynamoDBcontroller中的save方法是什么样的:

public <T> void save(T objectToSave) {
    logger.log("Saveing object " + objectToSave);
    getMapper().save(objectToSave);
    logger.log("Saved object " + objectToSave);
}

从DB方法获得:

public <T> T get(Class<T> objectClass, String id) {
    logger.log("Getting object class " + objectClass + ", where id was " + id);
    T data = getMapper().load(objectClass, id);
    logger.log("Get data " + data);
    if(data instanceof Product){
        logger.log("Product Class found");
        logger.log(data.toString());
    }
    return data;
}

我知道我需要转换器才能做好,所以我为复杂的对象类创建了通用转换器,为枚举创建了其他映射器:

对象:

public class ObjectConverter<T extends Object> implements DynamoDBTypeConverter<String, T> {

ObjectMapper objectMapper = new ObjectMapper();


@Override
public String convert(T object) {

    try {
        return objectMapper.writeValueAsString(object);
    } catch (JsonProcessingException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
    throw new IllegalArgumentException("Unable to parse JSON");
}

@Override
public T unconvert(String object) {
    try {
        T unconvertedObject = objectMapper.readValue(object, new TypeReference<T>() {
        });
        return unconvertedObject;
    } catch (JsonParseException e) {
        e.getMessage();
    } catch (JsonMappingException e) {
        e.getMessage();
    } catch (IOException e) {
        e.printStackTrace();
    }
    throw new IllegalArgumentException("Unable to parse to JSON");
}

枚举:

public class EnumConverter<T extends Object> implements DynamoDBTypeConverter<String, List<T>> {

@Override
public String convert(List<T> objects) {
    //Jackson object mapper
    ObjectMapper objectMapper = new ObjectMapper();
    try {
        String objectsString = objectMapper.writeValueAsString(objects);
        return objectsString;
    } catch (JsonProcessingException e) {
        //do something
    }
    return null;
}

@Override
public List<T> unconvert(String objectsString) {
    ObjectMapper objectMapper = new ObjectMapper();
    try {
        List<T> objects = objectMapper.readValue(objectsString, new TypeReference<List<T>>() {
        });
        return objects;
    } catch (JsonParseException e) {
        //do something
    } catch (JsonMappingException e) {
        //do something
    } catch (IOException e) {
        //do something
    }
    return null;
}

我正在使用POSTMAN对此进行测试,这就是我发送的JSON的外观:

{"id":"3bdc1372-4f67-493e-92d7-db3b529fe3bd","name":"bąkiKacpraPoEdycji","calories":1500,"fat":400.0,"carbo":20.0,"protein":40.0,"productKinds":["MEAT"],"author":{"name":"Plejer Annołn","id":"testID2"},"media":{"name":"heheszki","url":"http://blabla.pl","mediaType":"IMAGE"},"approved":false}

更多详情:

产品[媒体];无法转换属性:com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMappingException com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMappingException:Product [Media];无法转换属性

0 个答案:

没有答案