使用manyToMany,ManyToOne发布实体

时间:2019-02-07 23:53:06

标签: rest spring-boot spring-data-jpa relationship

我一直在我的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]]

我尝试了很多事情,但是在此问题上待了三天后,我想寻求帮助(哭泣)。

谢谢你们,对不起,很长的帖子!

0 个答案:

没有答案