0

I used SpringBoot, and in the PUT method I check if the score exists then I want to update the score and also update the history by adding the latest score to it.

The Score Class:

    package thesisMongoProject;

import java.util.Date;
import java.util.List;

import javax.validation.constraints.NotBlank;

import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;

import com.fasterxml.jackson.annotation.JsonView;

@Document(collection = "score")
public class Score {
    @Id
    @NotBlank
    @JsonView(Views.class)
    private String score;
    @NotBlank
    @JsonView(Views.class)
    private String player;
    @NotBlank
    @JsonView(Views.class)
    private String code;
    @JsonView(Views.class)
    private Date date;
    private List<History> history;



    public String getScore() {
        return score;
    }
    public void setScore(String score) {
        this.score = score;
    }
    public String getPlayer() {
        return player;
    }
    public void setPlayer(String player) {
        this.player = player;
    }
    public String getCode() {
        return code;
    }
    public void setCode(String code) {
        this.code = code;
    }
    public List<History> getHistory() {
        return history;
    }
    public void setHistory(List<History> history) {
        this.history = history;
    }
    public Date getDate() {
        return date;
    }
    public void setDate(Date date) {
        this.date = date;
    }
    @Override
    public String toString() {
        return "Score [score=" + score + ", player=" + player + ", code=" + code + ", history=" + history + ", date="
                + date + "]";
    }



}

The ScoreRepository:

 package thesisMongoProject.Repository;

import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.stereotype.Repository;

import thesisMongoProject.Score;
import thesisMongoProject.ScoreDto;

@Repository
public interface ScoreRepository extends MongoRepository<Score, String>{

    public Score findByScore(String score);
    public void save(ScoreDto scoredto, String score);

}

But the PUT method save a new instance into the MongoDB instead of updating the existing one

The PUT method:

//Update Score By ID
    @PutMapping("/{score}")
    public ResponseEntity<?> updatePlayerByID(
            @PathVariable("score")String score,
            @RequestBody @JsonView(Views.class) @Valid Score score1){

        Score findscore = srepo.findByScore(score); 
        if(findscore == null)
            return ResponseEntity.status(404).body("There is not Score!");
        else {

            history = new ArrayList<History>();
            h = new History();
            h.setScore(score1.getScore());
            h.setDate(score1.getDate());
            history.add(h);
            score1.setHistory(history);
            srepo.save(score1);
            return ResponseEntity.ok(score1);
        }
    }

Also i tried to use ScoreDTO and @PatchMapping like this:

The ScoreDTo Class:

package thesisMongoProject;

import java.util.List;


public class ScoreDto {

    private String score;
    List<History> history;
    public String getScore() {
        return score;
    }
    public void setScore(String score) {
        this.score = score;
    }
    public List<History> getHistory() {
        return history;
    }
    public void setHistory(List<History> history) {
        this.history = history;
    }


}

And the PATCHMAPPING:

@PatchMapping("/{score}")
    public ResponseEntity<?> updateByScore(
            @PathVariable("score")String score,
            @RequestBody   ScoreDto score1){
        Score findscore = srepo.findByScore(score);
        if(findscore == null)
            return ResponseEntity.status(404).body("There is not Score!");
        else {
            srepo.save(score1, score);
            return ResponseEntity.ok(score1);
        }

    }

but in my console I have an error:

org.springframework.data.mapping.PropertyReferenceException: No property save found for type Score! Did you mean 'date'?

could you help me how can i update the existing field of score, please?!

saharsa
  • 467
  • 1
  • 7
  • 24

1 Answers1

0

The primary key of a database should not be mutable. If there are multiple players with the same score, the earlier players' data would be replaced.

Ideally, for updating an existing document where id and all its new fields are known, something like this can be done:

score1.setScore(score);
srepo.save(score1);

Assuming score is the id of the document that is to be updated and score1 contains all other fields correctly, this will replace the existing document with id score with the new one score1.

In the first code ( the PUT method ), score1 should have the same id as findscore, then it will update the existing document.

        Score findscore = srepo.findByScore(score); 
    if(findscore == null)
        return ResponseEntity.status(404).body("There is not Score!");
    else {

        history = new ArrayList<History>();
        h = new History();
        h.setScore(score1.getScore());
        h.setDate(score1.getDate());
        history.add(h);

Also, for the exception you are getting, this save method

public void save(ScoreDto scoredto, String score);

can't be handled by the spring data repository automatically, you will have to define its implementation. More on what kind of methods can be defined or not here. The Standard save method in the repository can be used to achieve the required.

Saheb
  • 1,392
  • 3
  • 13
  • 33
  • thank you for your answer, but the score is ID in my class. how can i set the score of my pathVariable where I want to update my filed with score of pathVariable. – saharsa May 09 '20 at 15:53
  • I mean if i do the score1.setscore(score) i do not loose the new score which is in pathVariable? – saharsa May 09 '20 at 15:54
  • This is a very bad database design, where the primary key of the object is mutable. – Saheb May 09 '20 at 15:56
  • The primary keys of the database should be immutable. Read here: https://stackoverflow.com/questions/3838414/can-we-update-primary-key-values-of-a-table – Saheb May 09 '20 at 15:57
  • so, your suggestion is i define other primary key, instead of score which is not unique, am i right? – saharsa May 09 '20 at 16:01
  • 1
    Correct. Think of the case, where two players have the same score. – Saheb May 09 '20 at 16:01
  • from logic of view, if i define other primary key for Score Class, user must give this key as a field of PathVariable and i do not want this – saharsa May 09 '20 at 16:02
  • 1
    I don't know your complete use case, but if you are updating a player's score, then maybe send `playerId` and update the document by finding it using `playerId`. – Saheb May 09 '20 at 16:04