无法从PostgreSQL获取JPA数据:参数类型不匹配错误求助
问题排查:OneToMany关联查询参数类型不匹配错误
问题描述
存在一对OneToMany关联的实体GroupChat和MessengerUser,数据已成功存入PostgreSQL数据库,但调用接口获取群聊数据时抛出参数类型不匹配错误,提示Long类型参数与GroupChat类型不匹配。虽然Hibernate已成功查询到群聊数据,但无法正常返回对象。
错误日志
Hibernate: select g1_0.id,g1_0.analysed_date,g1_0.creation_date,g1_0.expiration_date,g1_0.group_chat_name,g1_0.total_current_participants,g1_0.total_messages,g1_0.total_participants,g1_0.total_sent_audio_files,g1_0.total_sent_gifs,g1_0.total_sent_photos,g1_0.total_sent_reactions,g1_0.total_sent_videos,g1_0.unique_id from group_chat g1_0 where g1_0.unique_id=? 2022-12-04T14:06:41.751Z ERROR 16704 --- [nio-8080-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed: org.springframework.dao.InvalidDataAccessApiUsageException: Argument [3] of type [java.lang.Long] did not match parameter type [com.example.demo.models.GroupChat (n/a)]] with root cause java.lang.IllegalArgumentException: Argument [3] of type [java.lang.Long] did not match parameter type [com.example.demo.models.GroupChat (n/a)]
实体模型代码
GroupChat实体
@Entity @Getter @Setter @NoArgsConstructor @Table(name = "GroupChat") public class GroupChat extends RepresentationModel<GroupChat> { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "id", nullable = false) private Long id; @Column(name = "uniqueId", nullable = false, unique=true) private UUID uniqueId; @Column(name = "expirationDate") private Date expirationDate; @Column(name = "analysedDate") private Date analysedDate; @Column(name = "creationDate") private Date creationDate; @Column(name = "totalParticipants", nullable = false) private int totalParticipants; @Column(name = "totalCurrentParticipants", nullable = false) private int totalCurrentParticipants; @Column(name = "totalMessages", nullable = false) private int totalMessages; @Column(name = "totalSentVideos", nullable = false) private int totalSentVideos; @Column(name = "totalSentPhotos", nullable = false) private int totalSentPhotos; @Column(name = "totalSentGifs", nullable = false) private int totalSentGifs; @Column(name = "totalSentAudioFiles", nullable = false) private int totalSentAudioFiles; @Column(name = "totalSentReactions", nullable = false) private int totalSentReactions; @Column(name = "groupChatName") private String groupChatName; @Column(name = "participants") @OneToMany(mappedBy="groupChatId", fetch = FetchType.LAZY, cascade = CascadeType.ALL) private List<MessengerUser> participants; }
MessengerUser实体
@Entity @Getter @Setter @NoArgsConstructor @Table(name = "MessengerUser") public class MessengerUser extends RepresentationModel<MessengerUser> { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "id", nullable = false) private Long id; @Column(name = "name", nullable = false) private String name; @Column(name = "profilePic") private int profilePic; @Column(name = "numberOfMessagesSent") private int numberOfMessagesSent; @Column(name = "numberOfPhotosSent") private int numberOfPhotosSent; @Column(name = "numberOfVideosSent") private int numberOfVideosSent; @Column(name = "numberOfGifsSent") private int numberOfGifsSent; @Column(name = "numberOfAudioFilesSent") private int numberOfAudioFilesSent; @Column(name = "numberOfReceivedReactions") private int numberOfReceivedReactions; @Column(name = "numberOfSentReactions") private int numberOfSentReactions; @Column(name = "userReactionsReceived", columnDefinition="TEXT") @Lob private String userReactionsReceived; @Column(name = "userReactionsSent", columnDefinition="TEXT") @Lob private String userReactionsSent; @Column(name = "addedToChat", columnDefinition="TEXT") @Lob private String addedToChat; @Column(name = "removedFromChat", columnDefinition="TEXT") @Lob private String removedFromChat; @Column(name = "firstRecordOfActivity") private Date firstRecordOfActivity; @Column(name = "lastRecordOfActivity") private Date lastRecordOfActivity; @Column(name = "userActiveStatus") private Boolean userActiveStatus; @Column(name = "firstMessage") private String firstMessage; @Column(name = "firstMessageDate") private Date firstMessageDate; @Column(name = "message") private int message; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name="group_chat_id", nullable=false) private GroupChat groupChatId; }
控制器与仓库代码
GroupChatController相关方法
@GetMapping("/{uniqueId}/chat") public GroupChat getGroupChatByUniqueId(@PathVariable(value = "uniqueId") UUID uniqueId) { GroupChat g = groupChatRepository.findByUniqueId(uniqueId); Link selfLink = linkTo(methodOn(GroupChatController.class) .getGroupChatByUniqueId(uniqueId)).withSelfRel(); g.add(selfLink); if (messengerUserRepository.findByGroupChatId(g.getId()).size() > 0) { Link ordersLink = linkTo(methodOn(MessengerUserController.class) .getMessengerUsersByGroupChatId(g.getId(),uniqueId)) .withRel("allMessengerUsers"); g.add(ordersLink); } return g; }
GroupChatRepository
public interface GroupChatRepository extends JpaRepository<GroupChat, Long> { GroupChat findByUniqueId(UUID uniqueId); }
错误原因及解决方案
错误根源
错误核心出现在**messengerUserRepository.findByGroupChatId(g.getId())**这一行:
- 在
MessengerUser实体中,关联字段定义为private GroupChat groupChatId;,对应的JPA查询方法findByGroupChatId预期接收的参数类型是GroupChat对象,而非Long类型的ID值。传入g.getId()(Long类型)就会触发类型不匹配错误。
修复步骤
调整MessengerUserRepository查询方法:
若要通过GroupChat的ID查询MessengerUser,需定义正确的查询方法:// 方法1:通过关联对象的ID查询 List<MessengerUser> findByGroupChatId_Id(Long groupChatId); // 方法2:判断是否存在数据(性能更优) boolean existsByGroupChatId_Id(Long groupChatId);修改控制器调用逻辑:
将原代码中的messengerUserRepository.findByGroupChatId(g.getId()).size() > 0替换为:if (messengerUserRepository.existsByGroupChatId_Id(g.getId())) { // 原逻辑不变 }额外规范建议:
- 实体关联字段命名需清晰,建议将
groupChatId改为groupChat,避免字段名与ID语义混淆:
对应的Repository方法改为@ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name="group_chat_id", nullable=false) private GroupChat groupChat; // 更名后更符合语义findByGroupChat_Id(Long groupChatId)或existsByGroupChat_Id(Long groupChatId)。
- 实体关联字段命名需清晰,建议将
内容的提问来源于stack exchange,提问作者MSmith
相关产品推荐
相关产品推荐

