互いに関連する 2 つのエンティティがあります。これらの 2 つのエンティティは、多対多の関係で互いにマップする必要がありますが、それぞれの関係のタイムスタンプ (発生したとき) も必要なので、中間テーブルを使用してそれらをマップしようとしています。
当初、関係は 1 対多でしたが、ビジネス ロジックがこれを必要とするため、実際には多対多が必要であることに気付きました。親と子の関係があるため、構造は同じですが、今回は、子も複数の親を持つ必要があります。
私の BaseEntity は、他のすべてのエンティティに存在するフィールドを含む抽象クラスです。
@Data
@MappedSuperclass
public abstract class BaseEntity {
@Id
@Min(100)
@Max(Integer.MAX_VALUE)
@GeneratedValue(strategy = GenerationType.IDENTITY)
protected Long id;
@CreationTimestamp
@Column(name = "Created_At", updatable = false)
protected ZonedDateTime createdDate;
@UpdateTimestamp
@Column(name = "Updated_At")
protected ZonedDateTime updatedDate;
@NotNull
@Column(name = "Is_Active")
protected Boolean active = true;
}
次に、多対多スタイルで関連付ける必要がある 2 つのエンティティがあります。これは私の最初のエンティティであり、親になる必要があります:
@Data
@Entity
@NoArgsConstructor
@AllArgsConstructor
@Table(name = "User")
@EqualsAndHashCode(callSuper = true)
@TypeDefs( {
@TypeDef(name = "json", typeClass = JsonStringType.class),
@TypeDef(name = "jsonb", typeClass = JsonBinaryType.class)
})
public class UserEntity extends BaseEntity {
@NotBlank
@Column(name = "User_Name", columnDefinition = "varchar(255) default 'N/A'")
private String userName;
@Nullable
@JoinColumn(name = "User_Id")
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private List<UserRole> roleList = new ArrayList<>();
}
私の 2 番目のエンティティは、子エンティティと見なされます。
@Data
@Entity
@NoArgsConstructor
@AllArgsConstructor
@Table(name = "Role")
@Where(clause = "is_active = true")
@EqualsAndHashCode(callSuper = true)
public class RoleEntity extends BaseEntity {
@NotBlank
@Column(name = "Name")
private String name;
@JsonIgnore
@JoinColumn(name = "Role_Id")
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private List<UserRole> userList = new ArrayList<>();
}
仲介エンティティもあります。
@Data
@Entity
@Getter
@NoArgsConstructor
@AllArgsConstructor
@Where(clause = "is_active = true")
@EqualsAndHashCode(callSuper = true)
@Table(name = "User_Role", uniqueConstraints= @UniqueConstraint(columnNames={"User_Id", "Role_Id"}))
public class UserRole extends BaseEntity {
// Adding @JsonIgnore here will only cause an error
@JoinColumn(name = "User_Id")
@ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY, optional = false, targetEntity = UserEntity.class)
private UserEntity user;
@JoinColumn(name = "Role_Id")
@ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY, optional = false, targetEntity = RoleEntity.class)
private RoleEntity role;
}
問題は、UserEntity を取得しようとすると、無限再帰が発生することです。
これまでのところ、@JsonIgnore、@JsonManagedReference、@JsonBackReference を使用してみましたが、機能しなかったか、適切に使用する場所や方法がわかりません。
要約:
- 多対多の関係によってマッピングされた 2 つのエンティティ。
- 中間エンティティと 1 対多 + 多対 1 の関連付けを使用して実装された多対多。
- UserEntity を表示するときに再帰を取得します。
更新:この質問への回答で説明されている別のアプローチを使用して、これを修正することができました。