为什么我必须输入ID(PK)-自动生成ID的问题

时间:2018-11-20 09:20:00

标签: java spring-boot primary-key crud

我正在通过租书方式创建租书方式。看起来像这样:

@PostMapping("/book")
public void purchaseBook(@RequestParam("userID") int userID, @RequestParam("bookID") int bookID) {
    bookRentalService.rentBook(userID, bookID);
}

输入用户ID和bookID后,如果有可用的图书,则将其添加到BookRentalDB中。

我所做的表之间的关系是这样的: enter image description here

出租实体

package bookrental.model.book;

import bookrental.model.account.User;
import lombok.*;

import javax.persistence.*;

@Entity
@Getter
@Setter
@EqualsAndHashCode
@AllArgsConstructor
@NoArgsConstructor
public class BookRentals {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private int id;
    @OneToOne
    private Book book;
    @OneToOne
    private User user;
}

在Service中创建此实体(BookRentals)的对象时遇到问题。它需要包含Book的对象和User的对象。我为此对象创建了构造函数,其中bookID仅使用Book,而userID仅使用User。我也要求在prepareBookToRent中放置BookRentals类的ID。在那种情况下,我无法创建它的对象。是否应该不自动生成?我应该怎么做才能使其正常工作。

package bookrental.service.book;

import bookrental.model.account.User;
import bookrental.model.book.Book;
import bookrental.model.book.BookRentals;
import bookrental.repository.book.BookRepository;
import bookrental.repository.book.BookRentalsRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class BookRentalService {

    private final BookRepository bookRepository;
    private final BookRentalsRepository bookRentalsRepository;

    @Autowired
    public BookRentalService(BookRepository bookRepository, BookRentalsRepository bookRentalsRepository) {
        this.bookRepository = bookRepository;
        this.bookRentalsRepository = bookRentalsRepository;
    }

    public void rentBook(int userID, int bookID) {
        if (bookRepository.doesBookExistsWithGivenID(bookID)) {
            Book bookToRent = bookRepository.findOne(bookID);
            if (bookToRent.isAvailable()) {
                updateBookAvailabilityAndSaveToDb(bookToRent);
                BookRentals preparedBookToRent = prepareBookToRent(userID, bookID);
                bookRentalsRepository.save(preparedBookToRent);
            } else {
                throw new IllegalArgumentException("Book is no available");
            }
        }
        throw new IllegalArgumentException("Book does not exist!");
    }


    private BookRentals prepareBookToRent(int userID, int bookID) {
        return new BookRentals(new Book(bookID),new User(userID)); // here im asked to input ID, too
    }

    private void updateBookAvailabilityAndSaveToDb(Book bookToRent) {
        bookToRent.setAvailable(false);
        bookRepository.save(bookToRent);
    }
}

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.book.rental.piotrek</groupId>
    <artifactId>BookRental</artifactId>
    <version>1.0-SNAPSHOT</version>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>8</source>
                    <target>8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.9.RELEASE</version>
    </parent>



    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.16.22</version>
        </dependency>
    </dependencies>

</project>

Staktrace

C:\Users\Admin\IdeaProjects\BookRental\src\main\java\bookrental\service\book\BookRentalService.java
Error:(39, 16) java: no suitable constructor found for BookRentals(bookrental.model.book.Book,bookrental.model.account.User)
    constructor bookrental.model.book.BookRentals.BookRentals(int,bookrental.model.book.Book,bookrental.model.account.User) is not applicable
      (actual and formal argument lists differ in length)
    constructor bookrental.model.book.BookRentals.BookRentals() is not applicable
      (actual and formal argument lists differ in length)

如上所述,就是这样:

enter image description here

1 个答案:

答案 0 :(得分:1)

您错了,您创建了所有args构造函数。您有3个属性。这意味着,您拥有所有带有3个参数而不是2个参数的args构造函数。

只需创建自定义构造函数即可。

public BookRentals (Book book, User user) {
// logic
}

ps:为什么不能从所有参数中排除某些参数:Java Lombok: Omitting one field in @AllArgsConstructor?

upd:评论表明有些疯狂。因此,如果一对一,请直接在实体上使用注释。如果您有很多,请考虑使用OneToMany,因为让多个用户租用同一本书是不现实的。

请参考此表格设计:How to implement one-to-one, one-to-many and many-to-many relationships while designing tables?