Hibernate, mysql - gdzie tkwi problem ?

0

Hej mam mały problem i nie mam pojęcia gdzie tkwi błąd. Możliwe, że źle relacje określiłem albo coś...
Chcę zrobić tabelki:

**Autor**
id
imię
nazwisko

**Kategoria**
id
nazwa

**Książka**
id
tytuł
id_kategorii
id_autora

Chcę aby książkę można było dodać tylko do istniejącego autora i kategorii czyli np. jeśli w bazie danych nie ma autora o id=1 to nie doda mi filmiku z id_autora=1.
Stwierdziłem, że będzie to relacja Autor OneToMany Książką ManyToOne Kategoria.
Napisałem coś takiego:

@Table
@Entity
public class Author {

    @Id
    @Column
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "first_name")
    private String firstName;

    @Column(name = "last_name")
    private String lastName;

    @OneToMany(
            mappedBy="author",
            fetch = FetchType.LAZY,
            cascade = CascadeType.ALL
    )
     private Set<Book> books;

     // geters and setters

@Entity
@Table
public class Book {

    @Id
    @Column
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column
    private String title;

    @ManyToOne(
            fetch = FetchType.LAZY,
            cascade = {
                    CascadeType.DETACH,
                    CascadeType.MERGE,
                    CascadeType.PERSIST,
                    CascadeType.REFRESH
            }
    )
    @JoinColumn(name="author_id", nullable=false)
    private Author author;

    @ManyToOne(
            fetch = FetchType.LAZY,
            cascade = {
                    CascadeType.DETACH,
                    CascadeType.MERGE,
                    CascadeType.PERSIST,
                    CascadeType.REFRESH
            }
    )
    @JoinColumn(name="category_id", nullable=false)
    private Category category;

    // getters and setters
@Table
@Entity
public class Category {

    @Id
    @Column
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column
    private String name;

    @OneToMany(
            mappedBy="category",
            fetch = FetchType.LAZY,
            cascade = CascadeType.ALL
    )
     private Set<Book> books;

     // getters and setters

I jestem wstanie wrzucić do bazy autora oraz kategorie ale nie mogę wrzucić książki, bo dostaję taki oto błąd:

"status": 400,
"error": "Bad Request",
"exception": "org.springframework.http.converter.HttpMessageNotReadableException",
"message": "JSON parse error: null; nested exception is com.fasterxml.jackson.databind.JsonMappingException: N/A\n at [Source: java.io.PushbackInputStream@191f3f96; line: 3, column: 14] (through reference chain: com.bowl.entity.Book["authorId"])",

0

Problem leży nie tu gdzie szukasz. Czytaj komunikaty błędów: błędy się pojawiają gdy wywołujesz metodę kontrolera. Problemem jest to że encje przekazujesz w wywołaniu kontrolera. Może się to udać ale wymaga trochę wysiłku. Innym sposobem jest wykorzystanie DTO.

0

A jak miałoby to wyglądać ? Nigdy nie używałem DTO, troszkę poczytałem teraz na necie co to jest i po co się tego używa.. ale nie doszedłem do jakiegoś wniosku dlaczego miałoby mi to pomóc ;c
Dodam, że error wyrzuca tylko jeśli chcę dodać Książkę. Jeśli "wsadzę" ją ręcznie do bazy danych, to mogę ją usunąć/edytować/wyświetlić.

    @PostMapping
    public ResponseEntity<Book> createBook(@Valid @RequestBody Book book, BindingResult bindingResult) {
        if(bindingResult.hasErrors()) {
            List errors = bindingResult.getAllErrors();
            return new ResponseEntity(errors, HttpStatus.BAD_REQUEST);
        }
        bookService.createBook(book);
        return new ResponseEntity<>(book, HttpStatus.CREATED);
    }

Pomiędzy mam jeszcze bookService wywołujący bookDao.createBook z adnotacją @Transactional

    @Override
    public void createBook(Book book) {
        Session session = sessionFactory.getCurrentSession();
        session.save(book);
    }

A problem z relacjami założyłem, ponieważ wcześniej ręcznie tworzyłem bazę danych i wszytko działało dobrze. Natomiast chciałem, aby hibernate tworzył mi bazę automatycznie i.. troszkę inaczej mi ją stworzył niż bym tego oczekiwał, ponieważ miałem złe relacje. Troszkę się pobawiłem z relacjami i bazę tworzy dobrze aczkolwiek występuje ten problem z dodawaniem książkek T_T

0

To pokaż jeszcze jsona Book, który przekazujesz do createBook.

0

Error dostajesz bo w jsonie, który chcesz zserializować do klasy Book podajesz pole authorId, a klasa Book takiego pola nie ma.

0
{
	"title":"tytul",
	"authorId":1,
	"categoryId":1
}

"status": 400,
"error": "Bad Request",
"exception": "org.springframework.http.converter.HttpMessageNotReadableException",
"message": "JSON parse error: null; nested exception is com.fasterxml.jackson.databind.JsonMappingException: N/A\n at [Source: java.io.PushbackInputStream@191f3f96; line: 3, column: 14] (through reference chain: com.bowl.entity.Book["authorId"])",

Teraz spróbowałem jeszcze w taki sposób

{
	"title":"tytul",
	"author_id":1,
	"category_id":1
}

"status": 500,
"error": "Internal Server Error",
"exception": "org.springframework.dao.DataIntegrityViolationException",
"message": "could not execute statement; SQL [n/a]; constraint [null]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement",
"path": "/books"

Możliwe, że coś pokręciłem, bo pierwszy raz robię coś takiego :v

0

@JsonIdentityInfo
@JsonIdentityReference
@JsonDeserialize

Proponuję poczytać o tym.

1 użytkowników online, w tym zalogowanych: 0, gości: 1