Java 自动生成的id不层叠在Hibernate子实体中的EmbeddedId上

Java 自动生成的id不层叠在Hibernate子实体中的EmbeddedId上,java,hibernate,jpa,spring-data-jpa,embeddable,Java,Hibernate,Jpa,Spring Data Jpa,Embeddable,当尝试插入一个实体-A和一个集合另一个实体B时,B应该从A获得自动生成的Id,但它的为null 尝试但失败: @MapsId(“taskPKId.storyId.id”)-相同的错误 @可嵌入 类故事ID{ @manytone(fetch=FetchType.Lazy) @JoinColumn(name=“STORY\u ID”) 长id; }//无法理解的空指针异常 mappedBy(“故事”)-相同错误 尝试使用mappedBy('story'),但在重复列中出现错误,因此必须使用inser

当尝试插入一个实体-
A
和一个
集合
另一个实体
B
时,
B
应该从
A
获得自动生成的
Id
,但它的
为null

尝试但失败:

  • @MapsId(“taskPKId.storyId.id”)
    -相同的错误
  • @可嵌入
    类故事ID{
    @manytone(fetch=FetchType.Lazy)
    @JoinColumn(name=“STORY\u ID”)
    长id;
    }
    //无法理解的空指针异常
  • mappedBy(“故事”)
    -相同错误
  • 尝试使用mappedBy('story'),但在重复列中出现错误,因此必须使用
    insertable=false
    updateable=false
    [Hibernate无法识别
    insertable=false
    @EmbeddedId
    ]
  • 我正在获取
    STORY\u ID=null
    ,因此
    saveAll
    storyRepository上失败。saveAll(stories)
    其中
    storyRepository
    Spring数据存储库

    @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;
    }
    
    @Table(name=“STORY”)
    @EqualsAndHashCode
    课堂故事{
    @身份证
    @GeneratedValue(stratergy=GenerationType.Auto)
    @列(name=“STORY\u ID”)
    长id;
    @列(name=“STORY\u name”)
    字符串名;
    //@OneToMany(cascade=ALL,mappedBy=“taskPKId.storyId.id”,fetch=FetchType.Lazy)//也尝试过这个
    @OneToMany(cascade=ALL,mappedBy=“story”,fetch=FetchType.Lazy)
    设定任务;
    }
    @表(name=“TASK\u XREF”)
    @EqualsAndHashCode
    课堂任务{
    @嵌入ID
    TaskPKId TaskPKId;
    @列(name=“TASK\u name”)
    字符串名;
    @manytone(fetch=FetchType.Lazy,可选=false)
    @JoinColumn(name=“STORY\u ID”,referencedColumnName=“STORY\u ID”,nullable=false,insertable=false,updateable=false)
    故事;
    }
    @可嵌入
    @EqualsAndHashCode
    类TaskPKId实现可序列化{
    TaskId TaskId;
    任务类型ID任务类型ID;
    StoryId StoryId;
    }
    @可嵌入
    @EqualsAndHashCode
    类StoryId实现可序列化{
    @列(name=“STORY\u ID”)
    长id;
    }
    
    表格:

  • 故事[
    故事ID
    故事名称
    ]
  • 任务外部参照[
    (任务ID(FK)、任务类型ID(FK)、故事ID(FK))
    PK、
    任务名称
    ]

  • 故事被插入(当然是在提交之前),但是失败了,因为
    Story\u ID
    作为空值发送给
    TASK\u XREF
    ,用于下一次插入

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

    可能的解决办法:

  • 如果一个故事拥有多个任务

    // 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;
    
  • 进一步阅读:

    我不太清楚为什么您的配置不起作用。我的一个项目中有一个类似的配置,运行得很好。但是,通过在Task类的manytone中添加@MapsId注释,我找到了一个解决方案。(有关MapsId的解释,请参阅)我还删除了insertable=false和updateable=false

    我没有让MapsId使用StoryId类,因此我将TaskPKID.StoryId的类型从StoryId更改为long。StoryId类似乎没有添加太多内容,因此希望这不是什么大问题。如果您找到解决方案,请在评论中告诉我

    顺便说一句,你的代码有很多问题。有很多拼写错误,并且在一个属性上有一个OneToMany映射不是集合(这是不允许的),这使得我调试问题更加困难。请确保下次在你的问题中发布质量更好的代码

    下面是我实现任务类的方式:

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

    您刚才重复了我在问题中提到的不起作用的内容。我看不出您在哪里提到了它。问题是,您正在尝试将单个类型(
    任务
    )字段映射到集合类型(
    集合
    )关系,你写了多种方法来表示
    故事;
    字段是如何映射的。你是对的,对不起-这里只设置了一个输入错误。
    @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;
        }
    }