【发布时间】:2021-11-05 07:47:55
【问题描述】:
我遇到了一个关于 hibernate jpa n...m 请求的问题。我的设置如下所示:
ChatRoom <--> Participant
需要注意的是映射表 RoomParticipant 有一个额外的活动字段:
Room -> RoomParticipant <- Participant
id id id
name roomId name
... participantId ...
active
在完成了一些教程并阅读了很多错误修复建议之后,我坚持使用这个设置(使用 Lombok):
@Entity
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@ToString
@EqualsAndHashCode
@Table(name = "rooms")
public class Room {
@Id
@GeneratedValue(generator = "uuid")
@GenericGenerator(name = "uuid", strategy = "uuid")
private String id;
@OneToMany(mappedBy = "room")
private List<RoomParticipant> roomParticipants = new ArrayList<RoomParticipant>();
public void addParticipant(Participant participant) {
RoomParticipant roomParticipant = new RoomParticipant(this, participant);
roomParticipants.add(roomParticipant);
participant.getRooms().add(roomParticipant);
}
}
// class annotations omitted
public class Participant {
@Id
private String id;
@Column
private String name;
@OneToMany(mappedBy = "participant", cascade = CascadeType.ALL, orphanRemoval = false)
@JsonIgnore
private List<RoomParticipant> rooms = new ArrayList<RoomParticipant>();
}
// class annotations omitted
public class RoomParticipant {
@EmbeddedId
@JsonIgnore
private RoomParticipantPK id;
@ManyToOne (fetch = FetchType.LAZY)
@MapsId("roomId")
@JsonIgnore
private Room room;
@ManyToOne (fetch = FetchType.LAZY)
@MapsId("participantId")
private Participant participant;
@Column
private boolean active;
public RoomParticipant(Room room, Participant participant) {
this.room = room;
this.participant = participant;
this.id = new RoomParticipantPK(room.getId(), participant.getId());
this.active = true;
}
}
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode
@Embeddable
public class RoomParticipantPK implements Serializable {
@Column(name="room_id")
private String roomId;
@Column(name="participant_id")
private String participantId;
}
除了 RoomParticipant 之外,类注解都是一样的。 现在,有了这个我有两个函数调用:一个打开一个新房间,这个工作!
public Room createRoom(String title, String userId, String username) {
Participant participant = participantRepository.findById(userId).orElse(createParticipant(userId, username));
Room room = new Room();
room.setTitle(title);
room.addParticipant(participant);
room.setArchived(false);
return chatRoomRepository.save(room);
}
调用此函数后,新房间已创建,新参与者已创建,room_participant 表已正确填写。
但现在我正在尝试加入具有以下功能的房间:
public Room joinRoom(String roomId, String sessionId, String username) {
Participant participant = participantRepository.findById(sessionId).orElse(createParticipant(sessionId, username));
Room room = chatRoomRepository.findById(roomId).orElseThrow(() -> new InvalidRoomException(roomId));
room.addParticipant(participant);
return chatRoomRepository.save(room);
}
由于以下错误,这不起作用:
javax.persistence.EntityNotFoundException: Unable to find ...chatservice.model.entities.RoomParticipant with id ...chatservice.model.entities.RoomParticipantPK@cc9e297f
这两个函数都调用 createParticipant 这是这样的:
private Participant createParticipant(String userId, String username) {
return participantRepository.save(new Participant(userId, username, new ArrayList<RoomParticipant>()));
}
存储库是 JpaRepository 的单行扩展
public interface ChatRoomRepository extends JpaRepository<Room, String> {}
public interface ParticipantRepository extends JpaRepository<Participant, String> {}
【问题讨论】:
-
在您的 RoomParticipantPK 上实现 toString 并查看缺少的 id。
-
感谢消息现在更加清晰:
javax.persistence.EntityNotFoundException: Unable to find com.syncpilot.chatservice.model.entities.RoomParticipant with id 2c9d90817bcaa8db017bcaa9223a0000 P-ID2(发送至http://localhost:8091/chatservice/v1/http/room/2c9d90817bcaa8db017bcaa9223a0000/join以下正文:displayName: 'name' participantId: 'P-ID2'。在我的数据库中,参与者表中有 P-ID2 的参与者. 另外,房间中确实存在 ID 为2c9d90817bcaa8db017bcaa9223a0000的房间。它只是没有在 room_participant 中添加条目 -
我还系统打印了我的 tostring 中的房间和参与者 ID - 没有丢失,toString 只被调用一次,并且两个 id 都已设置
标签: java database hibernate jpa