使用映射实体映射对象

时间:2016-01-14 00:11:58

标签: java hibernate jpa spring-boot

我试图弄清楚我做错了什么,但我正在学习hibernate注释并创建一个简单的库系统。基本上,一本书由一个人签出,并最终签到。以下是我如何配置它:

@Entity
@Table
public class Book {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    @Column(nullable = false, unique = true)
    private long barcode;
    @Column(nullable = false)
    private String name;
    @OneToMany
    @JoinTable(name = "checkoutsession", joinColumns = { @JoinColumn(name = "book") }, inverseJoinColumns = { @JoinColumn(name = "id")})
    private List<CheckOutSession> checkOutSessions;
}

@Entity
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;
    @Column(nullable = false, unique = true)
    private long barcode;
    @Column(name = "firstname")
    private String firstName;
    @Column(name = "lastname")
    private String lastName;
    @OneToMany
    @JoinTable(name = "checkoutsession", joinColumns = { @JoinColumn(name = "user") }, inverseJoinColumns = { @JoinColumn(name = "id")})
    private List<CheckOutSession> checkOutSessions;
}

@Entity
@Table(name = "checkoutsession", uniqueConstraints = {@UniqueConstraint(columnNames={"book", "checkIn"})})
public class CheckOutSession {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;
    @ManyToOne
    @JoinColumn(name="book", nullable=false)
    private Book book;
    @ManyToOne
    @JoinColumn(name="user", nullable=false)
    private User user;
    @Column(nullable = false)
    private java.sql.Timestamp checkOut;
    @Column
    private java.sql.Timestamp checkIn;
}

我无法弄清楚我的生活中我的配置是否错误。

[编辑]

当我试图拉书时,它选择了checkoutsession加入checkoutsession加入用户并且死掉了#34;未知列checkoutsess1_.check_in在&#39;字段列表&#39;;

[EDIT2]

更多上下文,我有一个扩展JpaRepository的BookDAO,当我调用findAll()时,它就是创建该查询的。

[EDIT3]

休息班:

@RestController
@RequestMapping("rest/books")
public class BookController {

@RequestMapping(method = RequestMethod.GET)
    public List findBooks() {
        return bookService.getAllBooks();
    }

}

服务:

@Component
public class BookService {

    private BookDao bookDao;

    public List getAllBooks() {
        return bookDao.findAll();
    }

    @Autowired
    public void setBookDao(BookDao bookDao) {
        this.bookDao = bookDao;
    }

}

DAO:

public interface BookDao extends JpaRepository<Book, Long> {

}

感谢您的帮助!

1 个答案:

答案 0 :(得分:1)

如果我运行你的代码并让JPA根据它看起来有效的实体生成表(至少它会运行)。

但是,您的映射对我来说似乎很奇怪,更具体地说是@JoinTable注释。 @JoinTable注释通常在您有连接表时使用(例如,在您的情况下为checkoutSession),但您不想映射它,因为除了两者之间的链接之外它不包含任何有用的信息那两张桌子。

在这种情况下,您使用@JoinTable注释如下:

@ManyToMany
@JoinTable(
    name = "checkoutsession", // Name of the join table
    joinColumns = @JoinColumn(name = "book"), // The column name in checkoutsession that links to book
    inverseJoinColumns = @JoinColumn(name = "user") // The column name in checkoutsession that links to user
)
private List<User> users;

因此,在这种情况下,您可以直接关联BookUser实体,而无需创建CheckoutSession实体。

但是,在您的情况下,您的联接表还包含两个时间戳,如果您在应用程序中需要这些时间戳,那么您不必使用@JoinTable,而只需使用@JoinColumn链接它们,例如:

@OneToMany(mappedBy = "book") // The field name in CheckoutSession that links to book
private List<CheckoutSession> checkOutSessions;

这是您Book实体中应该拥有的内容。请注意,在这种情况下,我们讨论的是字段名称,而不是列名称。您必须在CheckoutSession中输入映射回Book实体的字段名称。

有关@JoinTable注释的详细信息,建议您阅读以下答案:JPA "@JoinTable" annotationthis article