2017-03-02 16 views
1

我有三個實體:POST「內聯」子的ressource協會

@Entity 
public class Presentation { 
    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private Long id; 

    private String name; 

    @ManyToOne 
    private User author; 

    @ManyToMany 
    @JoinTable(joinColumns = @JoinColumn(name = "PRESENTATION_ID", referencedColumnName = "ID"), inverseJoinColumns = @JoinColumn(name = "TAG_ID", referencedColumnName = "ID")) 
    private Collection<Tag> tags; 

} 

@Entity 
public class Tag { 
    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private Long id; 

    @Column(unique = true, nullable = false) 
    private String name; 
} 

@Entity 
public class User { 
    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private Long id; 

    @Column(unique = true, nullable = false) 
    private String name; 
} 

每個實體都有自己的倉庫:

@Repository 
public interface PresentationRepository extends CrudRepository<Presentation, Long> { 
} 

@Repository 
public interface TagRepository extends CrudRepository<Tag, Long> { 
} 

@Repository 
public interface UserRepository extends CrudRepository<User, Long> { 
} 

所以演示文稿有一個作者(用戶)和標籤列表。

如果我創建或更新演示文稿,我必須將資源用戶和標籤關聯到該演示文稿。 根據Spring Data Rest - Association Resource的文檔,可以使用標頭Content-Type: text/uri-list分配它們。但在這種情況下,我必須做多次調用,來創建演示文稿,一個設置作者,另一個用於標籤,這樣的:

curl -i -X POST -H "Content-Type: application/json" -d '{"name": "P1"}' http://localhost:8080/api/presentations 

curl -i -X PATCH -H "Content-Type: text/uri-list" -d " 
http://localhost:8080/api/users/1" http://localhost:8080/api/presentations/1/author 

curl -i -X PATCH -H "Content-Type: text/uri-list" -d " 
http://localhost:8080/api/tags/1 
http://localhost:8080/api/tags/2" http://localhost:8080/api/presentations/1/tags 

我找到了一種方法繞過額外的呼籲作者並做了演示通話「內聯」(thanks to Chetan Kokil):

// WORK: 
curl -i -X POST -H "Content-Type: application/json" -d '{"name": "P1", "author": "http://localhost:8080/api/users/1"}' http://localhost:8080/api/presentations 

所以它爲我節省了額外的呼叫,並根據我的理解,它遵循ACID原則。

與我想要做的標籤列表一樣。所以,我想下面的調用:

// DON'T WORK: 
curl -i -X POST -H "Content-Type: application/json" -d '{"name": "P1", "author": "http://localhost:8080/api/users/1", "tags":["http://localhost:8080/api/tags/1","http://localhost:8080/api/tags/2"]}' http://localhost:8080/api/presentations 

而且我收到以下錯誤信息:

{ 
    "cause": { 
    "cause": null, 
    "message": "Can not construct instance of com.example.model.Tag: no String-argument constructor/factory method to deserialize from String value ('http://localhost:8080/api/tags/2')\n at [Source: N/A; line: -1, column: -1]" 
    }, 
    "message": "Could not read payload!; nested exception is com.fasterxml.jackson.databind.JsonMappingException: Can not construct instance of com.example.model.Tag: no String-argument constructor/factory method to deserialize from String value ('http://localhost:8080/api/tags/2')\n at [Source: N/A; line: -1, column: -1]" 
} 

我的問題是,是否有可能作出這樣的,如果是這樣,什麼是正確的語法?

謝謝大家。

回答

0

在寫我的問題,我找到了解決自己:)

也許這將幫助別人。

curl -i -X PATCH -H "Content-Type: application/json" -d '{"name": "P1", "author": "http://localhost:8080/api/users/1", "tags":[["http://localhost:8080/api/tags/1","http://localhost:8080/api/tags/2"]]}' http://localhost:8080/api/presentations 

如果你想爲一個列表/集合「內聯」成立該協會的資源,你必須把這些URI內陣列:

// WORK only for updating of a list that already contains at least one resource: 
[["a/b/c", "a/b/c"]] 

只有一個陣列不起作用。

// DON'T WORK: 
["a/b/c", "a/b/c"]` 

UPDATE:

看起來它只有在已經有相關的一些標籤的作品。所以這意味着這在創建新的Presentation實例時不起作用。如果該列表是空的,它給了我下面的錯誤:

Can not deserialize instance of com.example.model.Tag out of START_ARRAY token\n at [Source: N/A; line: -1, column: -1]" 

它是一個錯誤嗎? 我仍在尋找解決方案。