在尝试插入具有另一个实体A
的实体set
和B
时,B
应该从{{1}获取自动生成的Id
},但其A
。
尝试并失败:
null
-同样的错误。@MapsId("taskPKId.storyId.id")
//难以理解的空指针异常@Embeddable
class StoryId {
@ManyToOne(fetch = FetchType.Lazy)
@JoinColumn(name = "STORY_ID")
Long id;
}
-相同的错误
mappedBy("story")
和insertable=false
进行映射[Hibernate无法识别{{ 1}}] 我得到updatable=false
,因此insertable=false
在@EmbeddedId
上失败,其中STORY_ID = null
是 Spring Data存储库
saveAll
表格:
storyRepository.saveAll(stories)
,storyRepository
] @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))
答案 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
的实现结合在一起了(这可能会导致类似这样的意外行为)。
可能的解决方案:
如果一个故事拥有多个任务
// 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;
如果一个故事仅拥有一项任务
// 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