Identifier of an instance was altered when updating parent object in manytoone relation

27 Views Asked by At

I have an API using Spring Boot and it has a controller to update the Document model. I use the FieldService to find Service model, then I set the found field to document and finally save the Document. I do the same thing with Category and Organization and it works fine. However, when saving with field, it always throwing error, for example: identifier of an instance of com.major_project.digital_library.entity.Field was altered from c0a801b9-8ac0-1a60-818a-c04a8e4d000e to c0a801b9-8ac0-1a60-818a-c04a8e100008

c0a801b9-8ac0-1a60-818a-c04a8e4d000e is id of new field I want to update for my document and the other is old one.

I don't understand why I get this error.

My Document model:

@Entity
public class Document {
    @Serial
    private static final long serialVersionUID = 1L;

    @Id
    @UuidGenerator(style = UuidGenerator.Style.TIME)
    private UUID docId;

    @Column(nullable = false)
    private String docName;

    @Column(length = 65535)
    private String docIntroduction;

    @Column(nullable = false, unique = true)
    private String slug;

    private Timestamp uploadedAt;

    private Timestamp updatedAt;

    private boolean isDeleted;

    @ManyToOne
    @JoinColumn(name = "uploadedBy")
    private User userUploaded;

    @ManyToOne
    @JoinColumn(name = "verifiedBy")
    private User userVerified;

    @ManyToOne
    @JoinColumn(name = "orgId")
    private Organization organization;

    @ManyToOne
    @JoinColumn(name = "categoryId")
    private Category category;

    @ManyToOne
    @JoinColumn(name = "fieldId")
    private Field field;

    @PrePersist
    protected void onCreate() {
        uploadedAt = new Timestamp(System.currentTimeMillis());
        updatedAt = new Timestamp(System.currentTimeMillis());
    }

    @PreUpdate
    protected void onUpdate() {
        updatedAt = new Timestamp(System.currentTimeMillis());
    }

    @PreRemove
    protected void onRemove() {
        isDeleted = true;
    }
}

My Field model:

@Entity
public class Field implements Serializable {
    @Serial
    private static final long serialVersionUID = 1L;

    @Id
    @UuidGenerator(style = UuidGenerator.Style.TIME)
    private UUID fieldId;

    @Column(unique = true, length = 100, nullable = false)
    private String fieldName;

    @Column(unique = true, length = 100, nullable = false)
    private String slug;

    private Timestamp createdAt;

    private Timestamp updatedAt;

    private boolean isDeleted;

    @OneToMany(mappedBy = "field", cascade = CascadeType.ALL, orphanRemoval = true)
    private List<Document> documents = new ArrayList<>();


    @PrePersist
    protected void onCreate() {
        createdAt = new Timestamp(System.currentTimeMillis());
        updatedAt = new Timestamp(System.currentTimeMillis());
    }

    @PreUpdate
    protected void onUpdate() {
        updatedAt = new Timestamp(System.currentTimeMillis());
    }

    @PreRemove
    protected void onRemove() {
        isDeleted = true;
    }
}

My endpoint:

//    @Transactional
    @Operation(summary = "Cập nhật một tài liệu",
            description = "Trả về tài liệu vừa cập nhật. Tuỳ vào vai trò sẽ trả về trạng thái kèm theo.")
    @PutMapping(path = "/{slug}", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public ResponseEntity<?> updateDocument(@PathVariable("slug") String slug,
                                            @RequestPart("document") DocumentRequestModel documentRequestModel,
                                            @RequestPart(name = "file", required = false) MultipartFile multipartFile) {
        // Find user info
        UsernamePasswordAuthenticationToken auth = (UsernamePasswordAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
        String email = String.valueOf(auth.getPrincipal());
        User user = userService.findByEmail(email).orElseThrow(() -> new RuntimeException("Email is not valid"));
        // Find document
        Document document = documentService.findBySlug(slug).orElseThrow(() -> new RuntimeException("Document not found!"));

        modelMapper.map(documentRequestModel, document);
        if (multipartFile != null) {
            // Upload file
            FileModel gd = googleDriveUpload.uploadFile(multipartFile, documentRequestModel.getDocName());
            // Update file properties for document without overwriting existing properties
            document = modelMapper.map(gd, Document.class);
            document.setSlug(slugGenerator.generateSlug(document.getDocName().replace(".pdf", ""), true));
        }
        // Find category and field
        Category category = categoryService.findById(documentRequestModel.getCategoryId()).orElseThrow(() -> new RuntimeException("Category not found"));
        Field field = fieldService.findById(documentRequestModel.getFieldId()).orElseThrow(() -> new RuntimeException("Field not found"));
        Organization organization = organizationService.findById(documentRequestModel.getOrgId()).orElseThrow(() -> new RuntimeException("Organization not found"));
        document.setCategory(category);
        document.setField(field);
        document.setOrganization(organization);
        // Student must wait for the approval
        if (user.getRole().getRoleName().equals("ROLE_STUDENT")) {
            document.setVerifiedStatus(0);
        } else {
            document.setVerifiedStatus(1);
            document.setUserVerified(user);
        }
        // Save
        document = documentService.save(document);
        // Map to model to return
        DocumentResponseModel savedDocument = modelMapper.map(document, DocumentResponseModel.class);
        return ResponseEntity.ok(
                ResponseModel
                        .builder()
                        .status(200)
                        .error(false)
                        .message("Update successfully." +
                                (user.getRole().getRoleName().equals("ROLE_STUDENT") ? " Document is waiting for approval." : ""))
                        .data(savedDocument)
                        .build());
    }

Can anyone help me? Thank you so much for your support.

0

There are 0 best solutions below