Spring + Hibernate: создание дочернего элемента, сопоставленного с вымышленным родителем в отношениях OneToMany - PullRequest
1 голос
/ 11 июля 2020

У меня есть эти 2 объекта:

@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode
@Getter
@Entity
@Table(name = "BOOKS")
public class Book {

    @Id
    @GeneratedValue
    @Column(name = "ID")
    private long id;

    @NotNull
    @Column(name = "TITLE")
    private String title;

    @NotNull
    @Column(name = "AUTHOR")
    private String author;

    @NotNull
    @Column(name = "PUBLICATION_YEAR")
    private int publicationYear;

    @JsonBackReference
    @EqualsAndHashCode.Exclude
    @OneToMany(
            targetEntity = BookCopy.class,
            mappedBy = "book",
            cascade = CascadeType.ALL,
//            orphanRemoval = true,
            fetch = FetchType.LAZY
    )
    private List<BookCopy> bookCopies = new ArrayList<>();

    public Book(String title, String author, int publicationYear) {
        this.title = title;
        this.author = author;
        this.publicationYear = LocalDate.of(publicationYear, 1, 1).getYear();
    }
}
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode
@Getter
@Setter
@Entity
@Table(name = "BOOK_COPIES")
public class BookCopy {

    @Id
    @GeneratedValue
    @Column(name = "ID")
    private long id;

    @JsonManagedReference
    @NotNull
    @EqualsAndHashCode.Exclude
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "TITLE_ID")
    private Book book;

    @Enumerated(EnumType.STRING)
    @Column(name = "RENT_STATUS")
    private RentStatus rentStatus;

    public BookCopy(Book book, RentStatus rentStatus) {
        this.book = book;
        this.rentStatus = rentStatus;
    }

    public void setBook(Book book) {
        this.book = book;
        book.getBookCopies().add(this);
    }
}

Теперь, с помощью Hibernate, я создаю и сохраняю новый элемент BookCopy, отправляя его в мою веб-систему Spring JSON вроде этого:

{
    "book":{
        "id": 99999
    },
    "rentStatus": "HIRED"
}

Дело в том, что книги по этому идентификатору нет в таблице Book. Есть ли способ, с помощью которого я могу выполнить операцию сохранения BookCopy, чтобы сначала проверить наличие его родительских отношений? class:

@Repository
public class BookCopyDbService {
    @Autowired
    private BookCopyRepository bookCopyRepository;

    public BookCopy saveBookCopy(BookCopy bookCopy) {
        return bookCopyRepository.save(bookCopy);
    }
}

И класс CrudRepository, взаимодействующий с БД:

@Transactional
@Repository
public interface BookCopyRepository extends CrudRepository<BookCopy, Long> {
}

Возможно, я мог бы поместить несколько logi c в SaveBookCopy () BookCopyDbService, который сначала попробует найти эту книгу по идентификатору в таблице Book и сохранить BookCopy только в том случае, если книга была найдена в результате этого поиска, но мне было интересно, действительно ли в Hibernate есть какой-то механизм, который сделал это за меня.

1 Ответ

1 голос
/ 11 июля 2020

Вам нужно сначала получить сущность Book по идентификатору, а затем попытаться установить BookCopy. Если книга не закрывается, вы можете создать исключение.

@Service
public class BookService {
    @Autowired
    private BookRepository bookRepository;

    @Transactional
    public BookCopy saveBookCopy(BookCopy bookCopy,Long bookId) {
      Book book =bookRepository.findById(bookId).orElseThrow(()-> new 
       BookNotFoundException("Book not found."));
      book.getBookCopies().add(bookCopy);

        return book.getBookCopy();
    }

}

@ Transactional позаботится о вставке BookCopy в таблицу.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...