简体   繁体   English

Spring + Hibernate:在 OneToMany 关系中创建映射到虚构父级的子级

[英]Spring + Hibernate: creating child mapped to fictional parent in OneToMany relationship

I have these 2 entities:我有这两个实体:

@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);
    }
}

Now, through Hibernate I create and save a new BookCopy item, by sending through to my Spring Web system a JSON like this one: Now, through Hibernate I create and save a new BookCopy item, by sending through to my Spring Web system a JSON like this one:

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

The thing is, that book by that id does not exist in the Book table.问题是,该 id 的书在 Book 表中不存在。 Is there a way, in which I can have this BookCopy save operation first verify the existence of its parent relationship?有没有办法,我可以让这个 BookCopy 保存操作首先验证其父关系的存在?

UPDATE: Adding classes taking care of saving in DB:更新:添加负责保存在数据库中的类:

First, the DBService class:一、DBService class:

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

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

And the CrudRepository class, interfacing with the DB:和 CrudRepository class,与数据库接口:

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

Probably, I could put some logic in BookCopyDbService's saveBookCopy(), which would first try to find that book by ID in the Book table, and save BookCopy only if a book was found in that search, but I was wondering if Hibernate actually had some mechanism in place which did that for me.可能,我可以在 BookCopyDbService 的 saveBookCopy() 中添加一些逻辑,它首先会尝试在 Book 表中按 ID 查找该书,并且仅当在该搜索中找到一本书时才保存 BookCopy,但我想知道 Hibernate 是否真的有一些为我做到这一点的机制到位。

You need to first fetch the Book entity by the id and then try to set the BookCopy.您需要先通过 id 获取 Book 实体,然后尝试设置 BookCopy。 If book doesn't exsits, then you can throw exception.如果 book 不存在,那么你可以抛出异常。

@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 will take care of inserting the BookCopy into the table. @Transactional 将负责将 BookCopy 插入表中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM