2017-05-24 115 views
0

我正在使用Spring Boot,使用Hibernate和Maven作爲存儲庫管理器的JPA開發Rest API。在我的模型我有類Club使用Spring Boot的RESTful API中的循環依賴關係

@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 
 
    }

上述類與類Coach一個@OneToOne關係:

@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@Id@GeneratedValue註釋。

最後,我也有控制器類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裏面有一個循環(無限)的依賴關係。俱樂部擁有具有俱樂部如此這般教練... X( 這也將與@OneToMany relationship between俱樂部and Player`發生......

我發現這個解決方案:Link我只是使用@JsonIdentityInfo註釋類聲明中使用這個解決方案的問題是信息,我不會用(試想在Player@OneToMany關係)的開銷此外,你可以在上面的鏈接見:。

「但是,JSON id引用在整個圖中必須是唯一的,而JPA id只需要在同一個實體中是唯一的。 「」

所以,我必須使用UUID作爲JPA id字段。

我還發現了另一種可能的解決方案:Spring HATEOAS。在這種情況下,我可以將鏈接(href)添加到某些屬性中,只需要「請求」即可。但似乎春天HATEOAS有一些限制,如支持嵌入資源...

那麼,我應該遵循哪種方法?還有其他解決方案嗎?

很快,我打算在iOS應用程序中使用此API(我不知道它是否有所不同)。

對不起我的英文不好......來自巴西X問候)

+0

第二種方法看起來像Spotify的網頁API [鏈接](https://api.spotify.com/v1/albums/0sNOF9WDwhWunNAHPD3Baj/tracks?offset=0&limit=50) 。每張專輯都有一個href鏈接。 –

+0

只是爲了這種情況,這涉及到我:[爲什麼我討厭HATEOAS](https://jeffknupp.com/blog/2014/06/03/why-i-hate-hateoas/) –

+0

要解決循環引用,你應該打破兩個對象的鏈接。你可以看到註釋JsonManagedReference和JsonBackReference。 – dabaicai

回答

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; 
} 
+0

它適用於我。這聽起來像個好主意。僅供參考:[用於Spring REST API的DTO轉換實體](http://www.baeldung.com/entity-to-and-from-download-for-a-java-spring-application)。 –