MappingException 实体映射中的重复列:models.Book 列:author_id(应使用 insert="false" update="false" 进行映射)

MappingException Repeated column in mapping for entity: models.Book column: author_id (should be mapped with insert="false" update="false")

我总是遇到异常,当我尝试

Book book = new Book(); 
book.setAuthor_id(4);
book.setTitle("test");

作者 class:

public class Author {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private long id;

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

    @OneToMany(fetch = FetchType.EAGER, mappedBy = "author")
    private Set<Book> books;
    // getters and setters

图书class:

public class Book {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private long id;

    @Column(name = "title")
    private String title;

    @Column(name = "author_id")
    private long author_id;

    @ManyToOne(optional = false, cascade = CascadeType.ALL)
    @JoinColumn(name = "author_id")
    private Author author;
    //getters and setters

我在没有 private long author_id 的情况下尝试,但后来我无法设置作者 ID 我该如何解决?

这是因为您将 author_id 列映射到 Book 中的多个非 read-only 字段(author_idauthor)。这是不允许的,因为如果它们有不同的值,当 updating/inserting 它的值 updating/inserting 时,Hibernate 不知道它应该为 author_id 列使用哪个值。

因此要么删除其中之一,要么将其中之一配置为 read-only :

要将 author_id 配置为 read-only ,您可以这样做:

@Column(name = "author_id" , insertable=false, updatable=false)
private long author_id;

要将 Author 配置为 read-only ,您可以这样做:

@ManyToOne(optional = false, cascade = CascadeType.ALL)
@JoinColumn(name = "author_id", insertable=false, updatable=false)
private Author author;

更好的解决方案是确保只有一个字段映射到 author_id ,所以我会删除 author_id 字段。

要为一本书配置作者,最好先从数据库中查询作者。它还可以帮助验证具有给定 Id 的作者是否真的存在。否则,如果没有具有该 ID 的作者,则在保存 Book 时将违反其 FK 约束。由于您已经获得了 Author 实例,您可以简单地使用它来配置新书的作者。

如果你真的想节省一个数据库调用来获取作者,你可以考虑使用 EntityManagergetReference() 来获取作者代理,这样你就可以用它来配置新书的作者:

Author author = entityManager.getReference(Author.class , 4);

Book book = new Book(); 
book.setAuthor(author);
book.setTitle("test");

有关 getReference()

行为的更多详细信息,另请参阅