我正在使用Spring Boot开发Rest API,使用Hibernate和Maven作为存储库管理器开发JPA。在我的模型中,我有班级Club
:
@Entity
@Table( name = "CLUB")
public class Club {
/**
* Id da entidade
*/
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
/**
* Atual técnico do clube.
*/
@OneToOne(mappedBy = "actualClub")
private Coach coach;
//Outros atributos, getters e setters
}
上述课程与班级@OneToOne
之间存在Coach
关系:
@Entity
@Table(name = "COACH")
public class Coach extends Person {
/**
* Clube atual do técnico.
*/
@OneToOne
@JoinColumn(name = "CLUB_ID")
private Club actualClub;
//Outros atributos, getters e setters
}
课程Person
还有一个带有@Id
和@GeneratedValue
注释的 id 属性。
最后,我还有控制器类ClubController
,它可以处理一些请求,如下所示:
@RestController
public class ClubController {
/**
* Instância da classe de serviços da entidade <i>Club</i>
*/
@Autowired
private ClubService clubService;
/**
* Retorna JSON que representa o clube com o 'id' especificado.
*
* @param id Identificador do clube a ser buscado.
* @return ResponseEntity Objeto com detalhes da requisição HTTP, como o Status.
*/
@RequestMapping(value = "/clubs/{id}", produces = MediaType.APPLICATION_JSON_VALUE,
method = RequestMethod.GET)
public ResponseEntity<?> getClubById(@PathVariable Long id) {
final Club club = this.clubService.findById(id);
if (club != null) {
return new ResponseEntity<>(club, HttpStatus.FOUND);
} else {
return new ResponseEntity<>("Não encontrado", HttpStatus.NOT_FOUND);
}
}
/*Entre outros métodos...*/
}
问题是:在GET
/clubs/{id}
中,返回的JSON内部有一个循环(无限)依赖。俱乐部有一个教练,有一个俱乐部,所以它... ...(
这也适用于@OneToMany relationship between
分会and
播放器......
我找到了这个解决方案:Link。我只需要在类声明中使用@JsonIdentityInfo
注释。此解决方案的问题是我不会使用的信息开销(只需考虑@OneToMany
与Player
的关系)。此外,正如您在上面的链接中所看到的那样:
“但是,JSON id引用在整个图形中必须是唯一的,而JPA id只需要在同一个实体中是唯一的。”“
因此,我必须将UUID用于JPA id字段。
我还找到了另一种可能的解决方案:Spring HATEOAS。在这种情况下,我可以为某些属性添加链接(href),只需将请求“按需”。但是看起来Spring HATEOAS有一些限制,比如支持嵌入资源......
那么,我应该遵循哪种方法?还有其他解决方案吗?
很快,我打算在iOS应用程序中使用此API(我不知道它是否有所不同)。
抱歉我的英语不好......来自巴西的问候x)
答案 0 :(得分:1)
用@JsonIgnoreProperties
注释两个关系
如下
// Employee entity, owning side of relationship
@ManyToOne(cascade = CascadeType.ALL)
@JsonIgnoreProperties("employee")
private Department department;
// Department side, inverse side of relationship
@OneToMany(mappedBy = "department")
@JsonIgnoreProperties("department")
private Collection<Employee> employee;
答案 1 :(得分:0)
创建自己的DTO(https://en.wikipedia.org/wiki/Data_transfer_object)
可以解决此问题数据传输对象(DTO)是一种Java结构,仅用于组织数据以传输到另一个系统。它是根据需要创建的,没有不相关或私人信息,也没有循环引用。
例如:
private Map<String, Object> makeClubDTO(Club club) {
Map<String, Object> dto = new LinkedHashMap<String, Object>();
dto.put("id", club.getId());
dto.put("coach", club.getCoach().getId());
return dto;
}