Aye Chan Aung Thwin
Aye Chan Aung Thwin

Reputation: 125

Spring Boot JPA update after fething ID is not working

@Autowired
LessonService lsnService;

    @PutMapping(path = "/{id}")
    public ResponseEntity<Object> updateLesson(@PathVariable("id") Long id, @Valid @RequestBody LessonDto dto) {
        try {
            lsnService.findById(id);
            dto.setId(id);
            lsnService.save(dto);
            return ResponseEntity.ok(dto);
        }
        catch (Exception e) {
            ApiErrorMessage errorMessage = new ApiErrorMessage();
            errorMessage.setStatusCode(400L);
            errorMessage.setMessage(e.getMessage());
            errorMessage.setDescription("The server cannot or will not process the request due to an apparent client error");
            return ResponseEntity.badRequest().body(errorMessage);
        }
    }

Here's my problem. When I remove lsnService.findById(id);, update is working.

If I didn't add that code if a user update with unexisting ID, it will save another data. Another problem is when I remove dto.setId(id);, both method from lsnService; findById(id); and save(dto); are working! But as you can see, repo must update the entity but it won't!!!

So, I tried to put @Transactional in saving. And I even try putting Thread.sleep(5000); 5 secs delay between those two services. Like this,

lsnService.findById(id);
Thread.sleep(5000);
dto.setId(id);
lsnService.save(dto);

But it doesn't work either!

    @Autowired
    private LessonJpaRepository repo;

    @Override
    public LessonDto findById(Long id) {
        // TODO Auto-generated method stub
        Lesson lesson = repo.getOne(id);
        LessonDto dto = new LessonDto(lesson);
        return dto;
    }

    @Override
    public void save(LessonDto dto) {
        // TODO Auto-generated method stub
        repo.save(dto.getEntity());
        System.out.println(dto.getId()+dto.getTitle()+dto.getStructure()+dto.getExplanation());
    }

And then, I check output of that dto. It's all there! repo is not saving it! It's so strange to me. Got any ideas?

public class LessonDto {

    private Long id;

    @NotNull(message = "Title must not be null")
    @NotBlank(message = "Title must not be blank")
    @ValidLessonTitle(message = "Title must begin with uppercase character")
    private String title;

    @NotNull(message = "Structure must not be null")
    @NotBlank(message = "Structure must not be blank")
    private String structure;

    @NotNull(message = "Explanation must not be null")
    @NotBlank(message = "Explanation must not be blank")
    private String explanation;

    public LessonDto() {

    }

    public LessonDto(Lesson lesson) {
        this.id=lesson.getId();
        this.title=lesson.getTitle();
        this.structure=lesson.getStructure();
        this.explanation=lesson.getExplanation();
    }

    @java.beans.Transient
    public Lesson getEntity() {
        Lesson lesson = new Lesson();
        lesson.setId(this.id);
        lesson.setTitle(this.title);
        lesson.setStructure(this.structure);
        lesson.setExplanation(this.explanation);
        return lesson;
    }

    //getters and setters
}

This is the entity

@Entity
public class Lesson implements Serializable {

    /**
     * 
     */
    private static final long serialVersionUID = 2239534946567783017L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "title")
    private String title;

    @Column(name = "structure")
    private String structure;

    @Column(name = "explanation")
    private String explanation;

    //getters and setters
}

Upvotes: 0

Views: 1250

Answers (1)

Antoniossss
Antoniossss

Reputation: 32527

There are 2 ways to make that work

  1. Update instance that is retured by findById with values from DTO
  2. Dont use findById as it fetches entity pointer (at least) to the cache and this might be the origin of problems. Try to use existsById instead

Upvotes: 1

Related Questions