java.lang.IllegalStateException: несколько представлений одного и того же объекта [] объединяются. Отдельно: []; Отдельно: [] - PullRequest
0 голосов
/ 14 января 2019

У меня есть три объекта EntityA, EntityB и EntityC следующим образом:

EntityA:

import lombok.*;

import javax.persistence.*;
import java.util.HashSet;
import java.util.Set;

@Entity
@Table(name = "Entity_A")
@Getter
@Setter
@Builder
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(of = "locationA")
@ToString(of = "locationA")
public class EntityA {
    @Id
    @Column(name = "Name_A", length = 10)
    private String nameA;
    @Column(name = "Loc_A", length = 10)
    private String locationA;
    @ManyToMany(cascade = { CascadeType.MERGE })
    @JoinTable(
            name = "En_A_On_B",
            joinColumns = { @JoinColumn(name = "Name_A") },
            inverseJoinColumns = { @JoinColumn(name = "B_id") }
    )
    private Set<EntityB> bs;
}

EntityB:

import lombok.*;

import javax.persistence.*;
import java.util.HashSet;
import java.util.Set;

@Entity
@Table(name = "Entity_B")
@Setter
@Getter
@Builder
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(of = "locationB")
@ToString(of = "locationB")
public class EntityB {
    @Id
    @GeneratedValue
    @Column(name = "B_id")
    private int id;
    @Column(name = "Loc_B", length = 10)
    private String locationB;
    @ManyToMany(cascade = { CascadeType.MERGE })
    @JoinTable(
            name = "En_C_on_B",
            joinColumns = { @JoinColumn(name = "B_id") },
            inverseJoinColumns = { @JoinColumn(name = "C") }
    )
    private Set<EntityC> cs;
 }

EntityC:

 import lombok.*;

import javax.persistence.*;
import java.util.Set;

@Entity
@Table(name = "Entity_C")
@Getter
@Setter
@Builder
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(of = "c")
@ToString(of = "c")
public class EntityC {
    @Id
    @Column(name = "C", length = 20)
    private String c;    
}

СЕРВИСНЫЙ КЛАСС, ЧТОБЫ СОХРАНИТЬ:

@Service
@Slf4j
public class ServiceClass {
    @Autowired
    private EntityARepository entityARepository;

    private Set<EntityC> cs1 = new HashSet<>(asList(
            EntityC.builder().c("100").build(),
            EntityC.builder().c("10").build()
    ));

    private Set<EntityC> cs2 = new HashSet<>(asList(
            EntityC.builder().c("100").build(),
            EntityC.builder().c("200").build()
    ));

    //METHOD TO SAVE
    public void save() {
        Map<String, Set<EntityC>> map = new HashMap<>();
        map.put("B1", cs1);
        map.put("B2", cs2);

        List<String> bs = asList("B1", "B2");
        EntityA aa = EntityA.builder().nameA("abcd").locationA("mon").build();
        EntityA ab = EntityA.builder().nameA("abcde").locationA("money").build();

        bs.forEach(b -> {
            EntityB entityB = EntityB.builder().locationB("100xxx").build()
            entityB.getCs().addAll(map.get(b));            

            aa.getBs().add(entityB);
            ab.getBs().add(entityB);
        });

        entityARepository.save(aa);
        entityARepository.save(ab);
    }
}

Выполнение вышеуказанного кода вызывает следующее исключение

Причина: java.lang.IllegalStateException: несколько представлений одного и того же объекта [com.xxx.xxx.xxx.xxx.EntityC # 100] объединяются. Отдельно: [(c = 100)]; Отдельно: [(c = 100)]

Примечание: я исследовал в Интернете, но ни один из них не соответствует моему сценарию

Любая идея, как я могу исправить проблему

1 Ответ

0 голосов
/ 14 января 2019

Проблема здесь:

private Set<EntityC> cs1 = new HashSet<>(asList(
        EntityC.builder().c("100").build(), //this entity instance has the same identifier...
        EntityC.builder().c("10").build()
));

private Set<EntityC> cs2 = new HashSet<>(asList(
        EntityC.builder().c("100").build(), //...as this one
        EntityC.builder().c("200").build()
));

Вы пытаетесь сохранить две версии одной и той же сущности в одной единице работы. Представь, что ты положил:

EntityC.builder().c("100").name("A name").build()

в cs1 и:

EntityC.builder().c("100").name("Another name").build()

в cs2 вместо. Поскольку обе сущности имеют одинаковый id (c="100"), как Hibernate должен знать, какая версия «выигрывает»?

Попробуйте поместить один и тот же экземпляр из EntityC в оба набора, и проблема должна исчезнуть.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...