Mapper 2 object trong java

Mình có 2 Object mình tạm gọi là Object1() và Object2() ạ.
Object1() là data truyền lên, Object2() là data mình lấy từ database xuống.

Object1() :

{
"id": "4028828d",
"facilityResults": [
    {
        "id": "4024decaa62003b",
        "value": "1",
        "note": "hau nha 656251"
    },
    {
        "id": "4028828d7f003c",
        "value": "12"
        "note": "hy 52s"
    }
]} 

Object2():

{
"id": "4028828d",
"facilityResults": [
    {
        "id": "4028828d7f003c",
        "value": "12",
        "note": "hy 52s"
    },
    {
        "id": "4024decaa62003b",
        "value": "1"
        "note": "hau nha 656251"
    }
]}
  • facilityResults : được khai báo là Set facilityResults;

  • Set() có đặc điểm là thứ tự sắp xếp ngẫu nhiên. Khi mình dùng Mapper map 2 Object() nếu set() theo thứ tự thì oke, nhưng lúc Set() không theo thứ tự , lệch nhau thì gây ra lỗi.

  • Có cách nào mà không cần quan tâm tới thứ tự của Set() mà vẫn map() lại được với nhau không m.n.

Sorry, tớ không hiểu điều cậu muốn lắm.
Cậu muốn so sánh 2 json object kia (sau khi đã parse sang java object), phải không?
Tớ không hiểu map mà cậu nói tới là gì. Nếu được, cậu có thể cho tớ 1 chút code demo không?

3 Likes
public void updates(FacilityUpdateDTO updateDTO) {
        FacilityChecklist facilityChecklist = facilityChecklistRepository.findWithResultById(updateDTO.getId());

        Validate.notNullOrEmpty(facilityChecklist, HttpStatus.BAD_REQUEST, ErrorCode.OBJECT_OPTIONAL_NULL, "entity null");

        mapper.map(updateDTO, facilityChecklist);

        facilityChecklistRepository.save(facilityChecklist);
        // save step result
        facilityStepResultRepository.saveAll(facilityChecklist.getFacilityResults());
    }

FacilityUpdateDTO :

public class FacilityUpdateDTO {

    @NotBlank(message = "id can not be null or empty")
    @Size(max = 32, message = "id length must be less than or equal 32 characters")
    private String id;

    @Size(max = 20, message = "code length must be less than or equal 20 characters")
    private String code;

    private Set<FacilityStepResultUpdationDTO> facilityResults;

}

Entity FacilityChecklist :

public class FacilityChecklist extends SiteBase {

    @Column(name = "code", length = 20)
    private String code;

    @OneToMany(mappedBy = "facilityChecklist")
    @EqualsAndHashCode.Exclude
    @ToString.Exclude
    @JsonManagedReference
    private Set<FacilityStepResult> facilityResults;
    
}

Mỗi khi update của mình tới đoạn mapper.map(updateDTO, facilityChecklist) thì bị sai do
private Set facilityResults;private Set facilityResults; bị lệch thứ tự

Cảm ơn cậu nhé!
Cậu có code của mapper không @Tuan_Nguyen11? Share tớ method mapper#map(FacilityUpdateDTO, FacilityChecklist) làm gì được không cậu?

3 Likes

Mình dùng thư viện ModelMapper và sử dụng map(Object source, Object destination) của nó. Mình cảm ơn bạn nhiều.
Đây là code của thư viện ModelMapper

public void map(Object source, Object destination) {
    Assert.notNull(source, "source");
    Assert.notNull(destination, "destination");
    this.mapInternal(source, destination, (Type)null, (String)null);
}

Lỗi nó thông báo id bị đè lên nhau
org.springframework.orm.jpa.JpaSystemException: identifier of an instance of was altered from 4024decaa62003b to 4028828d7f003c;

Cảm ơn phản hồi của cậu nhé!
Cậu có thể ném tớ config của mapper của cậu được không? Nó có thể có ích giúp tớ loại trừ được một số giả thiết, cũng như để tớ hiểu cách cậu định nghĩa TypeMap.

Lỗi nó thông báo id bị đè lên nhau
org.springframework.orm.jpa.JpaSystemException: identifier of an instance of was altered from 4024decaa62003b to 4028828d7f003c;

Tớ không chắc lỗi này do thứ tự set khác nhau đâu. Cậu có chắc chắn việc này không? (thông qua debug hay bất cứ bằng chứng nào khác chẳng hạn). Dù thông qua error message, có vẻ như cậu có lý.
Tớ có để ý thấy cậu dùng Set (trong FacilityUpdateDTO) và Set (trong FacilityChecklist). Cậu đang cố map 2 set này với nhau, với khả năng cao cậu chưa override lại hàm hashCode(). Cậu có thể cho tớ xem nội dung của FacilityStepResultUpdationDTOFacilityStepResult được không?

Về phần Set, đúng như cậu nói, HashSet không đảm bảo thứ tự của các object. Vậy nên, tớ nghĩ có thể cậu nên cân nhắc sử dụng một cấu trúc dữ liệu khác (LinkedHashSet hoặc List chẳng hạn). Khi đó, trước khi cậu thực hiện map, cậu có thể sort các list theo thứ tự ID, rồi mới map (cậu thậm chí có thể cài đặt lại setter cho các list này, để khi cậu set, cậu sắp xếp luôn).
Có thể sẽ có cách khác, nhưng tớ chỉ giải thích được cách đó nếu như biết đủ thông tin.

Hope it helps!

2 Likes
83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?