JPA配置一对一关联后Swagger UI展示重复属性如何解决
问题根因
你当前使用了双向一对一关联,Lombok的@Data注解会给所有字段自动生成get/set方法,Swagger扫描接口模型时,除了扫描Employer本身的字段,还会把user关联对象里嵌套的employer属性的字段一并扫描展示,因此出现了重复字段的问题。
方案1:改用JPA继承实现字段复用(更推荐,符合你的业务场景)
你原本的需求就是复用User的字段给Employer和Employee使用,用JPA的@MappedSuperclass继承方案可以完全避免关联嵌套,从根源上解决重复字段问题:
- 修改User类,去掉
@Entity注解,添加@MappedSuperclass注解,删除和Employer的双向关联字段:
package hasancanozbek.hrms.Entities.abstracts; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import javax.persistence.*; @Data @AllArgsConstructor @NoArgsConstructor @MappedSuperclass public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "id") private int id; @Column(name = "email") private String email; @Column(name = "password") private String password; @Column(name = "telephone") private String telephone; }
- 修改Employer类,继承User,删除多余的userId、user关联字段:
package hasancanozbek.hrms.Entities.concretes; import hasancanozbek.hrms.Entities.abstracts.User; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import javax.persistence.*; @Data @AllArgsConstructor @NoArgsConstructor @Entity @Table(name = "employers") public class Employer extends User { @Column(name = "company_name") private String companyName; @Column(name = "company_website") private String companyWebsite; @Column(name = "verified") private boolean verified; }
这个方案下,Employer表会自动包含id、email等User类的所有字段,Swagger只会展示一层字段,不会出现重复。
方案2:保留现有一对一关联的修复方法
如果你不想改动现有表结构,只需要屏蔽嵌套字段的扫描即可:
- 给Employer类的user字段添加Swagger隐藏注解和序列化忽略注解:
如果是Swagger3/OpenAPI3:
@OneToOne @MapsId @JoinColumn(name = "user_id") @JsonIgnore @Schema(hidden = true) private User user;
如果是Swagger2:
@OneToOne @MapsId @JoinColumn(name = "user_id") @JsonIgnore @ApiModelProperty(hidden = true) private User user;
- 如果你需要在Employer的接口中暴露User的字段,手动添加透传的get/set方法即可:
// 透传User的email字段,其余password、telephone字段同理添加 public String getEmail() { return user == null ? null : user.getEmail(); } public void setEmail(String email) { if (user == null) user = new User(); user.setEmail(email); }
处理后Swagger就不会展示嵌套的重复字段,你需要的User字段也会直接平铺在Employer的模型下。
内容的提问来源于stack exchange,提问作者Hasan Can
相关产品推荐
相关产品推荐

