应用程序中的错误:org.hibernate.id.IdentifierGenerationException:试图从空的一对一属性分配 id

Posted

技术标签:

【中文标题】应用程序中的错误:org.hibernate.id.IdentifierGenerationException:试图从空的一对一属性分配 id【英文标题】:Error in app: org.hibernate.id.IdentifierGenerationException: attempted to assign id from null one-to-one property 【发布时间】:2021-12-18 09:24:51 【问题描述】:

我的应用程序出现错误:org.hibernate.id.IdentifierGenerationException:试图从空的一对一属性分配 id.. 我正在尝试在 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;

课程关键词:

@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;
    
    

课堂课程:

@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<>();

这里是关键字:

@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;
    

这是我的课程功能:

 @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);

    

每次我调用我的课程保存功能时,我都会得到

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】:

我尝试运行your code,但无法重现相同的异常。

但是,这段代码还有另一个问题。 EmbeddedId 需要手动初始化。

例如:

public class CourseKeyword 
        @EmbeddedId
        private CourseKeywordKey courseKeywordKey = new CourseKeywordKey();
// ...

以上修复后,正常持久化。

另见:

Hibernate exception with @MapsId, @EmbeddedId Use of @EmbeddedId and @MapsId causes NULL inserted (NOT NULL constraint violation)

【讨论】:

哇,它真的对我有用.. 非常感谢您的帮助和建议

以上是关于应用程序中的错误:org.hibernate.id.IdentifierGenerationException:试图从空的一对一属性分配 id的主要内容,如果未能解决你的问题,请参考以下文章

org.hibernate.id.UUIDHexGenera tor which does not generate IETF RFC 4122 compliant UUID values; cons

Caused by: org.hibernate.id.IdentifierGenerationException: ids for this class must be manually assig

Using org.hibernate.id.UUIDHexGenerator which does not generate IETF RFC 4122 compliant UUID values;

quarkus下的分布式ID怎么实现

Hibernate框架的主键生成策略

如何让 Hibernate 在 Oracle 上将 SequenceHiLoGenerator 用于 JPA GenerationType.AUTO?