Error in app: org.hibernate.id.IdentifierGenerationException: attempted to assign id from null one-to-one property

Viewed 333

I get error in my app: org.hibernate.id.IdentifierGenerationException: attempted to assign id from null one-to-one property.. I am trying to use Many-To-Many Relationship in JPA.

@Data
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode
@Embeddable
public class CourseKeywordKey implements Serializable {
    @Column(name = "course_id")
    private Long courseId;
    @Column(name = "keyword_id")
    private Long keywordId;
}

CourseKeywors:

@AllArgsConstructor
    @NoArgsConstructor
    @Getter
    @Setter
    @Entity
    public class CourseKeyword {
        @EmbeddedId
        private CourseKeywordKey courseKeywordKey;
        @CreationTimestamp
        private LocalDateTime created;
    
        @ManyToOne
        @MapsId("courseId")
        @JoinColumn(name = "course_id")
        Course course;
    
        @ManyToOne
        @MapsId("keywordId")
        @JoinColumn(name = "keyword_id")
        Keyword keyword;
    
    }

Class Course:

@AllArgsConstructor
@NoArgsConstructor
@Getter
@Setter
@Entity
public class Course {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
    @Lob
    private String description;
    @OneToMany(mappedBy = "course", cascade = CascadeType.ALL)
    List<CourseKeyword> keywords = new ArrayList<>();

here is Keyword:

@AllArgsConstructor
@NoArgsConstructor
@Getter
@Setter
@Entity
public class Keyword {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(unique=true)
    private String keyword;

    @CreationTimestamp
    private LocalDateTime created;

    @UpdateTimestamp
    private LocalDateTime updated;

    @OneToMany(mappedBy = "keyword", cascade = CascadeType.ALL)
    List<CourseKeyword> keywords = new ArrayList<>();


    public Keyword(String keyword) {
        this.keyword = keyword;
    }
}

here is my course function:

 @Override
    public void addNewCourse(CourseCreateDto courseCreateDto) {
        Teacher teacher = teacherRepository.findById(courseCreateDto.getTeacherId()).orElseThrow(() -> new CustomServiceException(NO_TEACHER_FOUND));
        Course course = modelMapper.map(courseCreateDto, Course.class);
        course.setCourseStatus(CourseStatus.ACTIVE);
        course.setTeacher(teacher);
        course.setUniqueCode(generateCourseUniqueCode());

      
        if(courseCreateDto.getKeywords().isEmpty()) throw new CustomServiceException("Course keyword list is empty!");

        course.getKeywords().addAll((courseCreateDto.getKeywords()
                .stream()
                .map(key -> {
                    Keyword keyword = keywordRepository.findKeywordsByKeyword(key.toLowerCase()).orElseThrow(() -> new CustomServiceException(""));
                    CourseKeyword courseKeyword = new CourseKeyword();
                    courseKeyword.setCourse(course);
                    courseKeyword.setKeyword(keyword);
                    return courseKeyword;
                })
                .collect(Collectors.toList())
        ));


        courseRepository.save(course);

    }

And each time I am calling my course save function I get

2021-11-04 08:39:43.200 ERROR 20702 --- [nio-8080-exec-3] o.a.c.c.C.[.[.[.[dispatcherServlet]      : Servlet.service() for servlet [dispatcherServlet] in context with path [/api] threw exception [Request processing failed; nested exception is org.springframework.orm.jpa.JpaSystemException: attempted to assign id from null one-to-one property [com.ceyentra.edulabInstitute.entity.CourseKeyword.course]; nested exception is org.hibernate.id.IdentifierGenerationException: attempted to assign id from null one-to-one property [com.ceyentra.edulabInstitute.entity.CourseKeyword.course]] with root cause

org.hibernate.id.IdentifierGenerationException: attempted to assign id from null one-to-one property [com.ceyentra.edulabInstitute.entity.CourseKeyword.course]
    at org.hibernate.id.ForeignGenerator.generate(ForeignGenerator.java:87) ~[hibernate-core-5.4.17.Final.jar:5.4.17.Final]
    at org.hibernate.mapping.Component$ValueGenerationPlan.execute(Component.java:509) ~[hibernate-core-5.4.17.Final.jar:5.4.17.Final]
    at org.hibernate.id.CompositeNestedGeneratedValueGenerator.generate(CompositeNestedGeneratedValueGenerator.java:97) ~[hibernate-core-5.4.17.Final.jar:5.4.17.Final]
    at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:115) ~[hibernate-core-5.4.17.Final.jar:5.4.17.Final]
    at org.hibernate.event.internal.DefaultMergeEventListener.saveTransientEntity(DefaultMergeEventListener.java:271) ~[hibernate-core-5.4.17.Final.jar:5.4.17.Final]
    at org.hibernate.event.internal.DefaultMergeEventListener.entityIsTransient(DefaultMergeEventListener.java:243) ~[hibernate-core-5.4.17.Final.jar:5.4.17.Final]
    at org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:175) ~[hibernate-core-5.4.17.Final.jar:5.4.17.Final]
    at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:113) ~[hibernate-core-5.4.17.Final.jar:5.4.17.Final]
    at org.hibernate.internal.SessionImpl.fireMerge(SessionImpl.java:811) ~[hibernate-core-5.4.17.Final.jar:5.4.17.Final]
    at org.hibernate.internal.SessionImpl.merge(SessionImpl.java:784) ~[hibernate-core-5.4.17.Final.jar:5.4.17.Final]
    at org.hibernate.engine.spi.CascadingActions$6.cascade(CascadingActions.java:261) ~[hibernate-core-5.4.17.Final.jar:5.4.17.Final]
    at org.hibernate.engine.internal.Cascade.cascadeToOne(Cascade.java:492) ~[hibernate-core-5.4.17.Final.jar:5.4.17.Final]
    at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:416) ~[hibernate-core-5.4.17.Final.jar:5.4.17.Final]
    at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:218) ~[hibernate-core-5.4.17.Final.jar:5.4.17.Final]
    at org.hibernate.engine.internal.Cascade.cascadeCollectionElements(Cascade.java:525) ~[hibernate-core-5.4.17.Final.jar:5.4.17.Final]
    at org.hibernate.engine.internal.Cascade.cascadeCollection(Cascade.java:456) ~[hibernate-core-5.4.17.Final.jar:5.4.17.Final]
    at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:419) ~[hibernate-core-5.4.17.Final.jar:5.4.17.Final]
    at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:218) ~[hibernate-core-5.4.17.Final.jar:5.4.17.Final]
    at org.hibernate.engine.internal.Cascade.cascade(Cascade.java:151) ~[hibernate-core-5.4.17.Final.jar:5.4.17.Final]
    at org.hibernate.event.internal.AbstractSaveEventListener.cascadeAfterSave(AbstractSaveEventListener.java:459) ~[hibernate-core-5.4.17.Final.jar:5.4.17.Final]
    at org.hibernate.event.internal.DefaultMergeEventListener.entityIsTransient(DefaultMergeEventListener.java:247) ~[hibernate-core-5.4.17.Final.jar:5.4.17.Final]
    at org.hibernate.event.internal.DefaultMergeEventListener.entityIsDetached(DefaultMergeEventListener.java:318) ~[hibernate-core-5.4.17.Final.jar:5.4.17.Final]
    at org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:172) ~[hibernate-core-5.4.17.Final.jar:5.4.17.Final]
    at org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:70) ~[hibernate-core-5.4.17.Final.jar:5.4.17.Final]
    at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:102) ~[hibernate-core-5.4.17.Final.jar:5.4.17.Final]
    at org.hibernate.internal.SessionImpl.fireMerge(SessionImpl.java:791) ~[hibernate-core-5.4.17.Final.jar:5.4.17.Final]
    at org.hibernate.internal.SessionImpl.merge(SessionImpl.java:778) ~[hibernate-core-5.4.17.Final.jar:5.4.17.Final]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_231]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_231]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_231]
    at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_231]
1 Answers
Related