【问题标题】:Composite-id on hibernate and spring休眠和弹簧上的复合ID
【发布时间】:2019-03-11 23:23:47
【问题描述】:

我试图在 Hibernate 和 Spring 上实现复合主键。

Catalog 有一个 catalogId,Book 有一个复合 id(catalogId 和 bookId),所以我使用 @Embeddable 注解实现了 BookId 类。

目录.java

@Entity
@Table(name = "catalog")
public class Catalog {

    private Integer id;
    private Timestamp date;


    private List<Book> books = new ArrayList<>();

    public Catalog() {
    }


    public Catalog(Timestamp date) {
        this.date = date;
    }

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    @Column(name = "date")
    public Timestamp getDate() {
        return date;
    }

    public void setDate(Timestamp date) {
        this.date = date;
    }



    @OneToMany(mappedBy="catalog")
    public List<Book> getBooks() {
        return books;
    }

    public void setBooks(List<Book> lineasCatalog) {
        this.books = books;
    }

}

BookId.java

@Embeddable
public class BookId implements Serializable {

    private static final long serialVersionUID = 1L;

    @Column(name = "id_catalog")
    private Integer idCatalog;

    @Column(name = "id_book")
    private Integer idBook;

    public BookId() {
    }

    public BookId(Integer idCatalog, Integer idBook) {
        this.idCatalog = idCatalog;
        this.idBook = idBook;
    }

    public Integer getIdCatalog() {
        return idCatalog;
    }

    public void setIdCatalog(Integer idCatalog) {
        this.idCatalog = idCatalog;
    }

    public Integer getIdBook() {
        return idBook;
    }

    public void setIdBook(Integer idBook) {
        this.idBook = idBook;
    }


    @Override
    public int hashCode() {
        return Objects.hash(getIdCatalog(), getIdBook());
    }


    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof BookId)) return false;
        BookId that = (BookId) o;
        return Objects.equals(getIdCatalog(), that.getIdCatalog()) &&
                Objects.equals(getIdBook(), that.getIdBook());

    }

}

Book.java

@Entity
@Table(name = "book")
public class Book {


    private BookId idBook;

    private Integer pages;
    private String title;

    private Catalog catalog;

    public Book(Integer pages, Catalog catalog) {
        this.pages = pages;
        this.catalog = catalog;
    }

    public Book() {
    }

    @EmbeddedId
    public BookId getIdBook() {
        return idBook;
    }

    public void setIdBook(BookId idBook) {
        this.idBook = idBook;
    }


    @Column(name = "pages")
    public Integer getPages() {
        return pages;
    }

    public void setPages(Integer pages) {
        this.pages = pages;
    }

    @Column(name = "title")
    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }


    @ManyToOne
    @JoinColumn(name="id_catalog")
    public Catalog getCatalog() {
        return catalog;
    }

    public void setCatalog(Catalog catalog) {
        this.catalog = catalog;
    }

}

服务:

@Transactional
    public void addCatalog(Catalog catalog, List<Book> books) {
        catalogDao.insert(catalog);

        for(int i=0; i<books.size(); i++) {
            BookId bid = new BookId();
            bid.setIdBook(i+1);
            bid.setIdCatalog(catalog.getId());          

            Book b = new Book();
            b.setIdBook(bid);

            b.setPages(books.get(i).getPages());
            b.setTitle(books.get(i).getTitle());
            b.setCatalog(catalog);

            catalog.getBooks().add(b);

            bookDao.insert(b);
        }
    }

我得到下一个错误:

oct 06, 2018 9:27:59 PM org.hibernate.mapping.RootClass checkCompositeIdentifier
WARN: HHH000038: Composite-id class does not override equals(): com.myapp.BookId
oct 06, 2018 9:27:59 PM org.hibernate.mapping.RootClass checkCompositeIdentifier
WARN: HHH000039: Composite-id class does not override hashCode(): com.myapp.BookId

我已经实现了 equals() 和 hashCode() 覆盖方法,所以我不明白为什么会出现问题。你能帮帮我吗?

【问题讨论】:

    标签: hibernate jpa orm jpa-2.0 hibernate-mapping


    【解决方案1】:

    有时,映射中的其他问题会触发休眠警告。我在您的问题中看到的一个问题是 Book.catalog 映射。您应该使用“派生身份”并添加 @MapsId 注释:

        @ManyToOne
        @MapsId("idCatalog") // maps idCatalog attribute of embedded id
        @JoinColumn(name="id_catalog")
        public Catalog getCatalog() {
            return catalog;
        }
    

    【讨论】:

    • 我添加了@MapsId("idCatalog") 但我得到下一个错误:org.hibernate.id.IdentifierGenerationException: 试图从空的一对一属性分配 id [com.myapp.Book .catalog]
    • 这可能是因为您在将图书写入数据库之前没有设置图书目录(即book.setCatalog(catalog))?
    • 是的,我编辑了我的帖子以在服务上添加方法“addCatalog”的内容。我发现了一些问题,但现在我得到了无限循环。该代码生成ID,但它从未在数据库中插入书籍
    • 嗯。我不确定我是否理解您如何获得无限循环并且没有插入书籍;因为您在循环内调用bookDao.insert(b);。无限循环在哪里?此外,您将书籍列表传递给您的方法并在其中构建每本书的副本以添加到目录并插入到数据库中,这听起来不太正确....
    • 我发现无限循环在这行:catalog.getBooks().add(b);如果我评论那一行,它不会插入到数据库中
    猜你喜欢
    • 2011-08-09
    • 2016-11-04
    • 2020-03-13
    • 1970-01-01
    • 2012-01-22
    • 2015-12-14
    • 1970-01-01
    • 2016-07-09
    • 1970-01-01
    相关资源
    最近更新 更多