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

时间:2019-05-18 15:16:52

标签: java hibernate jpa spring-data-jpa embeddable

在尝试插入具有另一个实体A的实体setB时,B应该从{{1}获取自动生成的Id },但其A

尝试并失败:

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

我得到updatable=false,因此insertable=false@EmbeddedId上失败,其中STORY_ID = null Spring Data存储库

saveAll

表格:

  1. 故事 [storyRepository.saveAll(stories)storyRepository]
  2. TASK_XREF [{@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; } PK,STORY_ID]

故事被插入(在提交课程之前),但是失败了,因为STORY_NAME在下一次插入时被作为空发送给(TASK_ID(FK), TASK_TYPE_ID(FK), STORY_ID(FK))

2 个答案:

答案 0 :(得分:1)

我不太确定为什么您的配置不起作用。在我的一个项目中,我有一个类似的配置,可以正常工作。通过在Task类的ManyToOne中添加@MapsId批注,我能够找到解决方案。 (有关MapsId的说明,请参见can someone please explain me @MapsId in hibernate?),我还删除了insertable = false和updatable = false。参见下面的代码。

我没有让MapsId与StoryId类一起使用,因此我将TaskPKID.storyId的类型从StoryId更改为long。 StoryId类似乎并没有增加太多,因此希望这不是什么大问题。如果您找到解决方案,请在评论中让我知道!

顺便说一句,您的代码有很多问题。有很多错字,并且在不是Collection的属性上存在一个OneToMany映射(这是不允许的),这使我更难以调试问题。请确保下次在您的问题中发布质量更好的代码。

这是我实现它的方式的Task类:

@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类:

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

答案 1 :(得分:0)

我不确定您想要实现什么,但是看起来您已经将@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