Hibernate:在多对多关系中插入数据,生成关联表的ID

5

假设我有两张表(Books和Authors之间是多对多的关系)

BOOKS
id
book_name

AUTHORS
id
author_name

BOOKS_AUTHORS
id
book_id
author_id

我将这些表映射为实体:

class Books  
{  
   @Id  
   long id;  

  @Column(name = "author_name")
   String name;


   @ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
   @JoinTable(name = "BOOKS_AUTHORS", 
              joinColumns = @JoinColumn(name = "book_id"),
              inverseJoinColumns = @JoinColumn(name = "author_id"))  
   List<Authots> authors;  

// setter, getters, adder  
}  

class Authors  
{  
   @Id  
   long id;  

   @Column(name = "author_name")
   String name;

   @ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
   @JoinTable(name = "BOOKS_AUTHORS", 
              joinColumns = @JoinColumn(name = "author_id"),
              inverseJoinColumns = @JoinColumn(name = "book_id"))  
   List<Books> books;  

// setter, getters, adder  
}  

现在,我尝试进行下一步操作。

public void addAuthor(final String bookName, final Author author)
{  
      final Book book = // get book from database by bookName
      if (book == null)
         throw new DataNotFoundException("Book not found :(");
      author.addBook(book);
      book.addAuthor(author);  
      entityManager.persist(author);  
}  

1) 我收到了一个异常,说BOOKS_AUTHORS记录的ID不能为空
2) 如何使用序列生成器为关系表BOOKS_AUTHORS生成ID


你可以使用外部脚本创建表格。 - vikas singh
4个回答

12

使用@ManyToMany无法创建具有id字段的联接表。

如果联接表中的id字段是必需的,则必须创建一个特殊的实体类(例如BookAuthor),并使用@ManyToOne/@OneToMany关系将其与图书和作者连接。

否则,您需要从BOOKS_AUTHORS表中删除id字段。


1
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private long id;

如果books_authors没有使用Hibernate进行映射,则使用数据库端的自动ID增量器。例如:
ALTER table book_authors CHANGE id long NOT NULL AUTO_INCREMENT;

这样我可以为作者实体和书籍实体生成ID。但是我需要为BOOKS_AUTHORS表生成ID,该表没有映射。 - Ilya
请参见我编辑后的答案,book_authors需要在数据库端自动递增其ID。 - Bitmap

0

尝试使用Projection

                  session.CreateCriteria(typeof (BOOKS_AUTHORS))
                           .SetProjection(Projections.Max("Id"))
                           .UniqueResult()

并在其基础上加1 :) 抱歉,这是.NET代码,我不熟悉Java,希望它能对您有所帮助。


0
在SpringBoot 1.5.3和spring-boot-starter-data-jpa中,您可以使用注释{@OrderColumn(name = "id")}。例如,您可以这样写:
    @ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
       @JoinTable(name = "BOOKS_AUTHORS", 
          joinColumns = @JoinColumn(name = "author_id"),
          inverseJoinColumns = @JoinColumn(name = "book_id")) 
    @OrderColumn(name = "id")             
    List<Books> books; 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接