OneToMany关系:引用id为null - spring boot



我是Spring-Data-Jpa的新手,所以我的问题可能有点傻。我被卡住了,很乐意得到帮助。

我有一个实体基础模型和两个实体具有以下结构:

@SuperBuilder(toBuilder = true)
@NoArgsConstructor
@AllArgsConstructor
@MappedSuperclass
public class BaseModel {
@Id
@GeneratedValue(generator = "system-uuid")
@GenericGenerator(name = "system-uuid", strategy = "uuid")
private String id;

...more attributes + getter & setter
}
@Entity
@SuperBuilder(toBuilder = true)
@AllArgsConstructor
@NoArgsConstructor
@Table(name = "project")
public class Project extends BaseModel {
@Column 
private String name;
@OneToMany(cascade = CascadeType.ALL,
fetch = FetchType.LAZY,
mappedBy = "project")
private List<Announcement> announcements = new ArrayList<>();
...more attributes + getter & setter
}
@Entity
@SuperBuilder(toBuilder = true)
@AllArgsConstructor
@NoArgsConstructor
@Table(name = "announcement")
public class Announcement extends BaseModel {
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name="project_id", nullable = false)
private Project project;
...more attributes + getter & setter
}

我坚持我的项目和公告实体如下:

public ProjectDTO createProject(CreateProjectRequest request) {
Project projectEntity = projectRepository.save(
Project.builder()
.announcements(request.getAnnouncements() != null
? request.getAnnouncements().stream().map(dto -> modelMapper.map(dto, Announcement.class)).toList()
: null)
.history(List.of(
HistoryEntry.builder()
.action(Action.PROJECT_CREATED.getValue())
.build())
)
.status(Status.NEW)
.name(request.getName())
.build()
);
return modelMapper.map(projectEntity, ProjectDTO.class);
}

我用值激活了JPA SQL语句跟踪。在这里,您可以看到第二个语句中的绑定参数3 (project的外键)为空。外键值的公告实体中也没有后续更新。

我怎么能解决这个问题?

Hibernate: 
/* insert de.keycon.salesservice.model.entity.Project
*/ insert 
into
project
(created, updated, name, status, id) 
values
(?, ?, ?, ?, ?)
09:36:32.263 [http-nio-8081-exec-3] TRACE org.hibernate.type.descriptor.sql.BasicBinder - binding parameter [1] as [TIMESTAMP] - [2022-11-29T09:36:32.254055300]
09:36:32.264 [http-nio-8081-exec-3] TRACE org.hibernate.type.descriptor.sql.BasicBinder - binding parameter [2] as [TIMESTAMP] - [2022-11-29T09:36:32.255054700]
09:36:32.264 [http-nio-8081-exec-3] TRACE org.hibernate.type.descriptor.sql.BasicBinder - binding parameter [3] as [VARCHAR] - [Demo-Project]
09:36:32.264 [http-nio-8081-exec-3] TRACE org.hibernate.type.descriptor.sql.BasicBinder - binding parameter [4] as [VARCHAR] - [NEW]
09:36:32.264 [http-nio-8081-exec-3] TRACE org.hibernate.type.descriptor.sql.BasicBinder - binding parameter [5] as [VARCHAR] - [2c9fe08184c287bc0184c287d3600000]
Hibernate: 
/* insert de.keycon.salesservice.model.entity.Announcement
*/ insert 
into
announcement
(created, updated, project_id, requirement, id) 
values
(?, ?, ?, ?, ?)
09:36:32.267 [http-nio-8081-exec-3] TRACE org.hibernate.type.descriptor.sql.BasicBinder - binding parameter [1] as [TIMESTAMP] - [2022-11-29T09:36:32.267443100]
09:36:32.267 [http-nio-8081-exec-3] TRACE org.hibernate.type.descriptor.sql.BasicBinder - binding parameter [2] as [TIMESTAMP] - [2022-11-29T09:36:32.267443100]
09:36:32.267 [http-nio-8081-exec-3] TRACE org.hibernate.type.descriptor.sql.BasicBinder - binding parameter [3] as [VARCHAR] - [null]
09:36:32.267 [http-nio-8081-exec-3] TRACE org.hibernate.type.descriptor.sql.BasicBinder - binding parameter [4] as [VARCHAR] - [Java 11, Cloud Native Experience, Maven or Gradle, Experience with Testing Framework]
09:36:32.267 [http-nio-8081-exec-3] TRACE org.hibernate.type.descriptor.sql.BasicBinder - binding parameter [5] as [VARCHAR] - [2c9fe08184c287bc0184c287d3730001]

编辑:我已经试过了:

@JsonManagedReference和@JsonBackReference.

改变获取。Lazy to fetch.Eager.

Set referencedColumnName = "id"

我回答我自己的问题。我改变了我的createProject方法,使项目在坚持之前也保持在公告中。现在id被正确地反映了。

public ProjectDTO createProject(CreateProjectRequest request) {
List<Announcement> announcements = request.getAnnouncements() != null
? request.getAnnouncements().stream().map(dto -> modelMapper.map(dto, Announcement.class)).toList()
: null;

Project project = Project.builder()
.announcements(announcements)
.history(List.of(
HistoryEntry.builder()
.action(Action.PROJECT_CREATED.getValue())
.build())
)
.status(Status.NEW)
.name(request.getName())
.build();
for (var announcement: announcements) {
announcement.setProject(project);
}
Project projectEntity = projectRepository.save(
project
);
return modelMapper.map(projectEntity, ProjectDTO.class);
}

相关内容

  • 没有找到相关文章

最新更新