濮阳建设工程网站,网站开发5人小组分工,天津网站建设哪家设计好,qq企业邮箱怎么注册前言在 JPA 中處理 多對多 (Many-to-Many) 關係#xff0c;不使用 ManyToMany 註解方式#xff0c;而是將這個關係拆解為兩個一對多的單向關係#xff0c;並為中間表創建一個獨立的Entity.代碼如下:Entity
Data
NoArgsConstructor
AllArgsConstructor
Builder
Table(name 不使用 ManyToMany 註解方式而是將這個關係拆解為兩個一對多的單向關係並為中間表創建一個獨立的Entity.代碼如下:Entity Data NoArgsConstructor AllArgsConstructor Builder Table(name users) public class User { Id GeneratedValue(strategy GenerationType.IDENTITY) private Long id; Column(name username, nullable false) private String username; Column(name password, nullable false) private String password; Column(name first_name, nullable false) private String firstName; Column(name last_name) private String lastName; Column(name email, nullable false, unique true) private String email; OneToMany(mappedBy user, cascade CascadeType.ALL, orphanRemoval true) private SetUserRole roles new HashSet(); public User(String username, String password, String firstName, String lastName, String email) { this.username username; this.password password; this.firstName firstName; this.lastName lastName; this.email email; } }Entity Data NoArgsConstructor AllArgsConstructor Builder Table(name roles) public class Role { Id GeneratedValue(strategy GenerationType.IDENTITY) private Long id; Column(length 20) private String name; public Role(String name) { this.name name; } OneToMany(mappedBy role, cascade CascadeType.ALL, orphanRemoval true) private SetUserRole userRoles new HashSet(); }Data Embeddable public class UserRoleId implements Serializable { // 與 UserRole.java 中 MapsId 的名稱一致 Column(name user_id) private Long userId; Column(name role_id) private Long roleId; public UserRoleId() { } public UserRoleId(Long userId, Long roleId) { this.userId userId; this.roleId roleId; } Override public boolean equals(Object o) { if (this o) return true; if (o null || getClass() ! o.getClass()) return false; UserRoleId that (UserRoleId) o; return Objects.equals(userId, that.userId) Objects.equals(roleId, that.roleId); } Override public int hashCode() { return Objects.hash(userId, roleId); } }Entity Data NoArgsConstructor AllArgsConstructor Builder Table(name users_roles) public class UserRole implements Serializable { // ID EmbeddedId private UserRoleId id; // 關係到 User, userId 對映到 UserRoleId 中的 userId ManyToOne(fetch FetchType.LAZY) MapsId(userId) JoinColumn(name user_id) private User user; // 關係到 Role ManyToOne(fetch FetchType.LAZY) MapsId(roleId) JoinColumn(name role_id) private Role role; Column(name assigned_at) private LocalDateTime assignedAt; }當我們 序列化 User 實例時Jackson 會拋出JsonMappingException異常顯示Exception如下:原因:這個錯誤發生在 Jackson 嘗試將您的 JPA 實體 User 序列化為 JSON 字串時Jackson 序列化器仍然發現了一個循環無限遞歸序列化錯誤原因:循環序列化的多對多結構 User - UserRole - RoleJackson 序列化 User。在序列化 User 的屬性時遇到 roles 集合 (SetUserRole)。序列化 UserRole 時遇到 User 實體 (ManyToOne private User user;)。Jackson 再次嘗試序列化這個 User 物件回到步驟 1形成無限循環。註: Jackson 預設的最大遞歸深度是 1000 層當達到這個限制時它會拋出這個錯誤以避免堆棧溢出StackOverflowError。任務針對 User 序列化為 JSON 字串時Jackson JSON 的無限遞迴問題提出處理雙向關係的方法。處理動作步驟一. 首先建立一個測試案例測試:Transactional SpringBootTest public class UserRoleRelationshipTest { Test void testReadUserRoleRelationship() { try { ListUser users userRepository.findAll(); // 獲取所有用戶 System.out.println(****** 獲取所有用戶: ******); ObjectMapper objectMapper new ObjectMapper(); objectMapper.registerModule(new JavaTimeModule()); String jsonArray objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(users); System.out.println(jsonArray); } catch (JsonProcessingException e) { e.printStackTrace(); } }步驟二. 預備測試資料已存 DB測試用Table users步驟三. 實作方案方案一使用JsonIgnore不想序列化某個屬性使用JsonIgnore註解來忽略關係中的某個屬性選項1public class User { . . . OneToMany(mappedBy user, cascade CascadeType.ALL, orphanRemoval true) JsonIgnore private SetUserRole roles new HashSet(); . . . }測試結果% mvn test選項2public class UserRole implements Serializable { . . . ManyToOne(fetch FetchType.LAZY) MapsId(userId) // 映射到 UserRoleId 中的 userId JoinColumn(name user_id) JsonIgnore private User user; ManyToOne(fetch FetchType.LAZY) MapsId(roleId) // 映射到 UserRoleId 中的 roleId JoinColumn(name role_id) JsonIgnore private Role role; . . . }測試結果% mvn test方案二使用JsonManagedReferences和JsonBackReferencesOneToMany(mappedBy user, cascade CascadeType.ALL, orphanRemoval true) JsonManagedReference private SetUserRole roles new HashSet(); OneToMany(mappedBy role, cascade CascadeType.ALL, orphanRemoval true) JsonManagedReference private SetUserRole userRoles new HashSet(); ManyToOne(fetch FetchType.LAZY) MapsId(userId) // 映射到 UserRoleId 中的 userId 屬性 JoinColumn(name user_id) JsonBackReference private User user; ManyToOne(fetch FetchType.LAZY) MapsId(roleId) // 映射到 UserRoleId 中的 roleId 屬性 JoinColumn(name role_id) JsonBackReference private Role role;執行測試結果: