自动生成的 ID 不会在 Hibernate 中的子实体中的 EmbeddedId 上级联

Auto generated id not cascading on EmbeddedId in child entity in Hibernate

尝试插入实体时 - Aset 另一个实体 BB 应该从 [= 获取自动生成的 Id 11=] 但它是 null.

尝试失败:

  1. @MapsId("taskPKId.storyId.id") - 同样的错误。
  2. @Embeddable class StoryId { @ManyToOne(fetch = FetchType.Lazy) @JoinColumn(name = "STORY_ID") Long id; } //不可理解的空指针异常
  3. mappedBy("story") - 同样的错误
    1. 尝试使用 mappedBy('story') 但重复列时出错,因此必须使用 insertable=falseupdatable=false 进行映射 [Hibernate 无法识别 insertable=false @EmbeddedId]

我得到 STORY_ID = null,因此 saveAllstoryRepository.saveAll(stories) 上失败,其中 storyRepositorySpring 数据存储库

@Table(name = "STORY")
@EqualsAndHashCode
class Story {
   @Id
   @GeneratedValue(stratergy=GenerationType.Auto)
   @Column(name="STORY_ID")
   Long id;

   @Column(name="STORY_NAME")
   String name;

   //@OneToMany(cascade=ALL, mappedBy="taskPKId.storyId.id", fetch = FetchType.Lazy) // tried this as well
   @OneToMany(cascade=ALL, mappedBy="story", fetch = FetchType.Lazy)
   Set<Task> task;
}

@Table(name = "TASK_XREF")
@EqualsAndHashCode
Class Task {
   @EmbeddedId
   TaskPKId taskPKId;

   @Column(name = "TASK_NAME")
   String name;

   @ManyToOne (fetch = FetchType.Lazy, optional = false)
   @JoinColumn(name = "STORY_ID", referencedColumnName = "STORY_ID", nullable = false, insertable = false, updatable = false) 
   Story story;
}

@Embeddable
@EqualsAndHashCode
Class TaskPKId  implements Serializable {
   TaskId taskId;
   TaskTypeId taskTypeId;
   StoryId storyId;
}

@Embeddable
@EqualsAndHashCode
class StoryId implements Serializable {
   @Column(name = "STORY_ID")
   Long id;
}

表格:

  1. 故事 [STORY_ID, STORY_NAME]
  2. TASK_XREF[(TASK_ID(FK), TASK_TYPE_ID(FK), STORY_ID(FK))PK,TASK_NAME]

故事被插入(当然在提交之前),但失败了,因为 STORY_ID 被作为 null 发送到 TASK_XREF 以进行下一次插入

我不确定你想要实现什么,但看起来你已经将 @OneToMany 注释与类似 @OneToOne 的实现结合起来(这可能会导致像这样的意外行为)。

可能的解决方案:

  1. 如果一个故事拥有多个任务

    // Story.java     
    @OneToMany(cascade=ALL, mappedBy="story", fetch = FetchType.Lazy)
    Set<Task> task; // basically Set, List or any other collection type
    // Task.java
    @ManyToOne (fetch = FetchType.Lazy, optional = false)
    @JoinColumn(name = "STORY_ID", referencedColumnName = "STORY_ID") 
    Story story;
    
  2. 如果一个故事只有一个任务

    // Story.java 
    @OneToOne(cascade=ALL, mappedBy="story", fetch = FetchType.Lazy)
    Task task;
    // Task.java
    @OneToOne (fetch = FetchType.Lazy, optional = false)
    @JoinColumn(name = "STORY_ID", referencedColumnName = "STORY_ID") 
    Story story;
    

延伸阅读: @OneToOne @OneToMany

我不太确定为什么您的配置不起作用。我在我的一个项目中有一个类似的配置,效果很好。但是,通过向任务 class 中的 ManyToOne 添加 @MapsId 注释,我能够找到解决方案。 (有关 MapsId 的解释,请参阅 can someone please explain me @MapsId in hibernate?)我还删除了 insertable=false 和 updatable=false。代码见下方。

我没有让 MapsId 与 StoryId class 一起工作,所以我将 TaskPKID.storyId 的类型从 StoryId 更改为 long。 StoryId class 似乎没有增加太多,所以希望这不是什么大问题。如果您找到解决方案,请在评论中告诉我!

顺便说一句,你的代码有很多问题。有一堆拼写错误,属性 上有一个 OneToMany 映射,它不是 Collection(这是不允许的)这让我更难调试问题。下次请确保 post 在您的问题中使用质量更高的代码。

这是任务 class 我实现它的方式:

@Entity
@Table(name = "TASK_XREF")
class Task {
    @EmbeddedId
    TaskPKId taskPKId;

    @Column(name = "TASK_NAME")
    String name;
    @MapsId("storyId")
    @ManyToOne(fetch = FetchType.LAZY, optional = false)
    @JoinColumn(name = "STORY_ID")
    Story story;

    //getters, setters

}

这里是 TaskPKID class:

@Embeddable
class TaskPKId  implements Serializable {
        long taskId;
        long taskTypeId;
        @Column(name="STORY_ID")
        long storyId;

    public long getTaskId() {
        return taskId;
    }

    public void setTaskId(long taskId) {
        this.taskId = taskId;
    }

    public void setTaskTypeId(long taskTypeId) {
        this.taskTypeId = taskTypeId;
    }
}