Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/376.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
java.lang.IllegalStateException:正在合并同一实体[]的多个表示形式。分离:[];分离:[]_Java_Hibernate_Jpa_Many To Many - Fatal编程技术网

java.lang.IllegalStateException:正在合并同一实体[]的多个表示形式。分离:[];分离:[]

java.lang.IllegalStateException:正在合并同一实体[]的多个表示形式。分离:[];分离:[],java,hibernate,jpa,many-to-many,Java,Hibernate,Jpa,Many To Many,我有三个实体EntityA、EntityB和EntityC,如下所示: 实体A: 要保存的服务类: @Service @Slf4j public class ServiceClass { @Autowired private EntityARepository entityARepository; private Set<EntityC> cs1 = new HashSet<>(asList( EntityC.builde

我有三个实体EntityA、EntityB和EntityC,如下所示:

实体A:

要保存的服务类:

@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.EntityC100]的多个表示形式。分离:[c=100];分离:[c=100]

注:我已经在互联网上进行了探索,但没有一个与我的场景相符


你知道我该如何纠正这个问题吗?问题就在这里:

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()
));
在cs1和:

而是在cs2中。既然两个实体都具有相同的id c=100,那么Hibernate如何知道哪个版本“获胜”


尝试将EntityC的同一实例放在两个集合中,问题就会消失

您是否尝试过像about CascadeType.MERGE:那样更改级联类型?您的Spring Boot和H2数据库代码运行得很好。我使用的是mssql。它正在为我引发异常。将CascadeType.MERGE更改为CascadeType.ALL,看看发生了什么。它引发了相同的异常它不会是实际场景中的同一个实例,而是两个不同的解组实例。我正在使用equals和hashCode方法。那么,恐怕同样的问题仍然存在。无论从何处获取实体,如果尝试使用相同的ID合并不同的实体实例,Hibernate无法自行决定哪个版本是正确的。您需要强制引用相等,否则它将不起作用。如果要保存EntityB和EntityC之间的关联,而不是保存整个未签名的EntityC状态,则需要使用repository.getOne获取对预先存在的EntityC的引用,并使用该实例而不是map.getb;在entityB.getCs.addAll中。。。Line使用Spring Boot和H2数据库时,操作代码工作正常。@EugenCovaci是否将调用包装以保存到事务中?如果不是,则entityARepository.saveaa和entityARepository.saveab会创建两个单独的事务,因此问题不会出现surface@crizzis无论entityARepository.save是否标记为@Transactional,它都能正常工作。顺便说一句,创建或不创建EntityArepositional.save transactional不会创建两个事务。
 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);
    }
}
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()
EntityC.builder().c("100").name("Another name").build()