当前位置: 首页 > 知识库问答 >
问题:

组织。冬眠PersistentObjectException:传递给Persistent的分离实体

宋凌龙
2023-03-14

初始数据。专业有很多科目。

专业JAVA

@Entity
@Table(name = "specialties")
public class Specialty implements Serializable {

    private Long id;
    private Set<Subject> subjects;

    @Id
    @GeneratedValue
    @Column(name = "specialty_id")
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    @OneToMany(mappedBy = "specialty")
    @Cascade(CascadeType.ALL)
    public Set<Subject> getSubjects() {
        return subjects;
    }

    public void setSubjects(Set<Subject> subjects) {
        this.subjects = subjects;
    }

    public void addSubject(Subject subject) {
        addSubject(subject, true);
    }

    public void addSubject(Subject subject, boolean set) {
        if (subject != null) {
            getSubjects().add(subject);
            if (set) {
                subject.setSpecialty(this, false);
            }
        }
    }

    public void removeSubject(Subject subject) {
        getSubjects().remove(subject);
        subject.setSpecialty(null);
    }
}

对于一个主题来说,专业不能为空。我希望它能以下一种方式工作:当我保存/更新/分离一个主题时,同样的操作必须应用于专业。当我删除一个主题时,专业不会发生任何变化。

主题JAVA

@Entity
@Table(name = "subjects")
public class Subject implements Serializable {
    private Long id;
    private Specialty specialty;

    @Id
    @GeneratedValue
    @Column(name = "subject_id")
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    @ManyToOne
    @JoinColumn(name = "specialty_id")
    @Cascade({CascadeType.PERSIST, CascadeType.MERGE, CascadeType.DETACH})
    public Specialty getSpecialty() {
        return specialty;
    }

    public void setSpecialty(Specialty specialty) {
        setSpecialty(specialty, true);
    }

    public void setSpecialty(Specialty specialty, boolean add) {
        this.specialty = specialty;
        if (specialty != null && add) {
            specialty.addSubject(this, false);
        }
    }
}

我写了一个集成测试。生成专业()和生成主题()这只是util方法。

@Before
public void initEntitities() {
    specialty = generateSpecialty();
    subject = generateSubject();
    subject.setSpecialty(specialty);

    subjectRepository.save(subject);
    entityManager.detach(subject);
}

@Test
public void testSaveSpecialtyViolate2of3UniqueField() {
    Subject subject1 = new Subject();
    subject1.setSemester(1);
    subject1.setUkrName("Тест матан UPD");
    subject1.setEngName("XXX");
    subject1.setCode("MT 23.O8");
    subject1.setCredit(6F);
    subject1.setSpecialty(specialty);

    subjectService.save(subject1);

    assertNotNull(subjectRepository.findOne(subject.getId()));
    assertNotEquals(subject.getUkrName(), subject1.getUkrName());
    assertEquals(subject.getSemester(), subject1.getSemester());
    assertEquals(subject.getSpecialty().getId(),
subject1.getSpecialty().getId());
    }

你可以在这张图片上看到测试结果。

subjectService在此处引发了异常。保存(主题1);

原因:org。冬眠PersistentObjectException:传递给Persistent:文凭的分离实体。实体专业

在测试开始时,将分离专业(您可以在图像上看到它。我使用entityManager.contains(专业)来检查它)。我认为问题在于下一步:当Hibernate试图保存subject1时,它首先从db中选择Speciality,Speciality将其状态更改为pesist。你知道我该如何修复它以及为什么会发生吗?

我应用了这个链接中的第一条建议,但对我没有帮助

共有1个答案

须鸿祯
2023-03-14

我认为这可能是因为你在“subject1.setSpecialty(speciality)”中重用了speciality,而在你的“initentities()”中,它可能与主题分离了。

 类似资料: