I would like to extend the basic entity to be compatible DynamoDB document, but I don't know how to extend the entity's child. Here is the code:

@Data
@Accessors(chain = true)
@ApiModel
public class Question {

    @NotNull
    @ApiModelProperty(value = "UUID", required = true)
    private UUID id;

    @NotBlank
    private String name;

    @ApiModelProperty(value = "List of answers")
    private List<Answer> answers = Collections.emptyList();

}

@Data
@Accessors(chain = true)
@ParametersAreNonnullByDefault
public class Answer {

    @NotNull
    @ApiModelProperty(value = "Question key", required = true)
    private UUID questionKey;

    @NotBlank
    @ApiModelProperty(value = "Answer in string format", required = true)
    private String value;
}

Here is the extended Answer Dynamo Document:

@DynamoDBTable(tableName = "question")
public class QuestionDocument extends Question {

    @DynamoDBHashKey
    @DynamoDBAutoGeneratedKey
    @Override
    public UUID getId() {
        return super.getId();
    }

    @DynamoDBAttribute
    @Override
    public Long getName() {
        return super.getName();
    }

    @DynamoDBAttribute
    @Override
    // Here is the problem, I don't know how to properly override answers, because this method expect Answer output.
    public Set<AnswerDocument> getAnswers() {
        return super.getAnswers();
    }
}

@DynamoDBDocument
@NoArgsConstructor
public class AnswerDocument extends Answer {

    @DynamoDBAttribute
    @Override
    public Long getValue() {
        return super.getValue();
    }
}

The problem is that I don't know how to properly overide extended QuestionDocument's getAnswers() method to return AnswerDocument extended as well.

Pls put me on the right track, how to do it with the inheritance how it's shown on the example above.

Thank you in advance.

2 Answers

1
SylarBenes On

From Java docs:

"The ability of a subclass to override a method allows a class to inherit from a superclass whose behavior is "close enough" and then to modify behavior as needed. The overriding method has the same name, number and type of parameters, and return type as the method that it overrides. An overriding method can also return a subtype of the type returned by the overridden method. This subtype is called a covariant return type."

So because AnswerDocument extends Answer, returning type AnswerDocument in a method that overrides a method with return type Answer is fine.

However, I don't think you want to just call super here, because it will get you a list of Answer and that doesn't seem to be the behaviour you want here. So if you need the behaviour from super, receive it's list of Answer, make your transformations, and then return a List of AnswerDocument.

@DynamoDBAttribute
@Override
public List<AnswerDocument> getAnswers() {
    List<Answer> answerlist = super.getAnswers();
    // transform them to AnswerDocument
    return answerDocumentList ;
}

This example assumes your AnswerDocuments are first present as Answers and are then transformed. If the QuestionDocument does not contain any Answers then the super method won't serve you at all and you'll have to write the code all yourself, but you can still do it in a method that overrides the original getAnswers(), but with return type AnswerDocument.

0
Govinda Sakhare On

You need to change the return type to Collection as List and Set belongs to different hierarchy.
I have made some changes, please check the below snippet and let me know if it meets your requirements.

Note: For brevity, I have removed other annotations.

Parent class:

class Question {

    private UUID id;

    private Long name;

    private List<Answer> answers = Collections.emptyList();

    // Change in the return type
    public Collection<Answer> getAnswers() {
        return answers;
    }

    public void setAnswers(List<Answer> answers) {
        this.answers = answers;
    }
}

Child class:

public class QuestionDocument extends Question {

    @Override
    public Collection<AnswerDocument> getAnswers() {
        return super.getAnswers();
    }
}