detached entity passed to persist spting boot with command save

I am testing my repository. In one of the tests I have to add a skill collection which consists of “skill-group” and “skill-detail”. I tested by making new objects of the latest, but when I try to test using an existing value in those 2 tables, I get “detached entity passed to persist” error.

I read other problems, but I couldn't really find a prober answer to my problem.

the error message is the dollowing:

org.springframework.dao.InvalidDataAccessApiUsageException: detached entity passed to persist: com.example.demo.skill_related.skill_group.SkillGroup; nested exception is org.hibernate.PersistentObjectException: detached entity passed to persist: com.example.demo.skill_related.skill_group.SkillGroup

The detail model:

public class SkillGroup {
@Id
@Column(name = "id", nullable = false)
@SequenceGenerator(
        name = "skillGroups_sequence",
        sequenceName = "skillGroups_sequence",
        allocationSize = 1)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "skillGroups_sequence")
private Long id;

@Column(name = "name", columnDefinition = "TEXT", unique = true, nullable = false)
private String name;

@Column(name = "type", columnDefinition = "CHAR(2)")
private char type;
}

The detail model:

public class SkillDetail {
@Id
@Column(name = "id", nullable = false)
@SequenceGenerator(
        name = "skillDetail_sequence",
        sequenceName = "skillDetail_sequence",
        allocationSize = 1)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "skillDetail_sequence")
private Long id;

@Column(name = "name", columnDefinition = "TEXT",  unique = true, nullable = false)
private String name;
}

The collection model:

public class SkillCollection {
@Id
@Column(name = "id", nullable = false)
@SequenceGenerator(
        name = "skillCol_sequence",
        sequenceName = "skillCol_sequence",
        allocationSize = 1)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "skillCol_sequence")
private Long id;

@ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL, optional = false)
@JoinColumn(name = "skill_group", referencedColumnName = "id", updatable = false)
private SkillGroup skillGroups;

@ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL, optional = false)
@JoinColumn(name = "skill_detail", referencedColumnName = "id", updatable = false)
private SkillDetail skillDetails;
}

My test looks like this:

    @Test
public void makeNewSkills() {

//        SkillGroup skillGroup = SkillGroup.builder()
//                .name("Gebruikersinteractie")
//                .type('B')
//                .build();

    SkillGroup skillGroup = skillGroupRepo.findSkillGroupByName("Gebruikersinteractie");

    SkillDetail skillDetail = SkillDetail.builder()
            .name("Advisceren")
            .build();

    SkillCollection skillCollection = SkillCollection.builder()
            .skillGroups(skillGroup)
            .skillDetails(skillDetail)
            .build();

    skillCollectionRepo.save(skillCollection);
}

1 answer

  • answered 2022-05-05 08:58 Yelderiny

    You cannot persist the SkillCollection object with SkillDetail and SkillGroup object attributes without adding the id attribute when creating the SkillDetail and SkillGroup objects.

    Because you're using findSkillGroupByName(), your SkillGroup object includes the id. Your SkillDetail object doesn't. You're just creating it right there and then which means it hasn't been persisted to the database and doesn't have an id yet. Without an id, this error will come up. If you persist your SkillDetail object first then your SkillCollection object you should be fine.

    SkillDetail skillDetail = SkillDetail.builder()
                .name("Advisceren")
                .build();
    
    skillDetailRepo.save(skillDetail); //this is what you need to add
    
    SkillCollection skillCollection = SkillCollection.builder()
                .skillGroups(skillGroup)
                .skillDetails(skillDetail)
                .build();
    
    skillCollectionRepo.save(skillCollection); //then this will work
    

How many English words
do you know?
Test your English vocabulary size, and measure
how many words do you know
Online Test
Powered by Examplum