我一直在我的API中避免使用@xToX关系,但最终想放手一搏,而我一直在努力。 我已经设法使get方法以任何递归的方式向我返回正确的信息(至少我参与了一部分),现在我想将数据与这些关系放到我的API中(到目前为止似乎可以正常工作)。 / p>
因此,我有一些对象,包括一本书,一本书的风格,一本书的类别和一个作者。 一本书只有一位作者(即使有时是错误的,但正如我只读科幻小说一样,它可以解决问题),而一位作家有很多书(与类别相同)。 一个样式可以有很多书,也可以有很多样式。
因此,我在本书的作者属性上使用了@ManyToOne
,在作者的books属性上使用了@OneToMany
(与类别相同)。
在样式和@ManyToMany
我希望能够使用作者和样式ID如下所述将书发布到我的API:
{
"isbn": "15867jhg8",
"title": "Le portrait de Dorian Gray",
"author": 1,
"category":1,
"style": [1,2,3]
}
我已经用@JsonBackReference
,@JsonManagedReference
,@JsonSerialize
,@JsonIdentityInfo
注释了我的属性,但我确实认为我可能做得太多了……
我不确定我使用@JsonSerialize还是@JsonIdentityInfo的方式。 为了使示例保持“简单”,我省略了无用的属性。
所以让我们开始吧。
首先上Book课:
@Entity
@JsonIdentityInfo(
generator = ObjectIdGenerators.PropertyGenerator.class,
property = "id"
)
public class Book implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(updatable = false, nullable = false)
private Integer id;
private String isbn;
private String title;
@ManyToOne
@JoinColumn(name="category_id", nullable = false)
@JsonBackReference(value = "category")
private BookCategory category;
@ManyToOne
@JoinColumn(name="author_id", nullable = false)
@JsonBackReference(value = "author")
private Author author;
@ManyToMany
@JsonManagedReference(value = "styles")
@JsonSerialize(using = BookStyleListSerializer.class)
private List <BookStyle> styles;
}
然后是作者课程:
@Entity
@JsonIdentityInfo (
generator = ObjectIdGenerators.PropertyGenerator.class,
property = "id"
)
public class Author implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(updatable = false, nullable = false)
private Integer id;
@OneToMany(mappedBy = "author")
@JsonManagedReference(value = "authorBooks")
@JsonSerialize(using = BookListSerializer.class)
private List <Book> books;
}
由于类别是相同的,所以我只粘贴它的books属性:
@OneToMany(mappedBy = "category")
@JsonManagedReference(value = "categoryBooks")
@JsonSerialize(using = BookListSerializer.class)
private List <Book> books;
最后是我的bookStyle类:
@Entity
@JsonIdentityInfo(
generator = ObjectIdGenerators.PropertyGenerator.class,
property = "id"
)
public class BookStyle implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(updatable = false, nullable = false)
private Integer id;
@ManyToMany
@JsonManagedReference(value = "styleBooks")
@JsonSerialize(using = BookListSerializer.class)
private List <Book> books;
}
序列化器是相同的,只是类型有所改变:
public class BookStyleListSerializer extends StdSerializer <List <BookStyle>> {
public BookStyleListSerializer() {
this(null);
}
public BookStyleListSerializer(Class<List<BookStyle>> t) {
super(t);
}
@Override
public void serialize(List <BookStyle> bookStyles, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
List<Integer> ids = new ArrayList <> ( );
for (BookStyle style: bookStyles){
ids.add(style.getId ());
}
jsonGenerator.writeObject ( ids );
}
}
根据我的理解(由于英语不是我的母语,我在编码时可能会在这里和那里误解了几件事):
@JsonBackReference
用于我们不想与@JsonManagedReference
相反的属性被序列化的@JsonSerialize
是自定义序列化程序,因此元素将按照我们希望的顺序进行序列化(在这种情况下,仅使用ID)对于你们中的某些人来说可能很明显:我编写的代码都不适合发布数据,这是例外,因为我通过API发布某些内容时收到了它(并且它加倍了,不是复制粘贴错误) :
.c.j.MappingJackson2HttpMessageConverter : Failed to evaluate Jackson deserialization for type [[simple type, class com.rz.librarian.domain.entity.Author]]: com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot handle managed/back reference 'categoryBooks': no back reference property found from type [collection type; class java.util.List, contains [simple type, class com.rz.librarian.domain.entity.Book]]
.c.j.MappingJackson2HttpMessageConverter : Failed to evaluate Jackson deserialization for type [[simple type, class com.rz.librarian.domain.entity.Author]]: com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot handle managed/back reference 'categoryBooks': no back reference property found from type [collection type; class java.util.List, contains [simple type, class com.rz.librarian.domain.entity.Book]]
我尝试了很多事情,但是在此问题上待了三天后,我想寻求帮助(哭泣)。
谢谢你们,对不起,很长的帖子!