org.hibernate.exception.ConstraintViolationException:键'PRIMARY'的重复条目

时间:2014-10-31 08:17:38

标签: mysql hibernate nhibernate-mapping hibernate-mapping

我有一个Book类,它与Author类有很多对应的映射。 所以在数据库中,表格是:Book -------- Book_Author -------作者。 Book_Author包含两列,分别是Book_Id和Author_Id。 现在每当应用程序启动时,保存或更新都没有问题,但是在第二次执行任何此操作时,存在重复的主键异常"重复条目' 123-147'关键' PRIMARY'"对应于插入操作发生两次 - 一个用于当前选择的作者值,另一个用于前一个请求。 我在记录器中使用了trace来检测变量的值。日志如下:

SQL:104 - update Book set Availability=?, Copies_Issued=?, Description=?, Image=?, In_Stock=?, Isbn=?, Published_Year=?, Publisher_Name=?, status=?, Title=?, Total_Stock=? where Book_Id=?
BasicBinder:83 - binding parameter [1] as [VARCHAR] - AVAILABLE
BasicBinder:83 - binding parameter [2] as [INTEGER] - 0
BasicBinder:83 - binding parameter [3] as [VARCHAR] - Test description
BasicBinder:83 - binding parameter [4] as [VARCHAR] - 1414741446090.jpg
BasicBinder:83 - binding parameter [5] as [INTEGER] - 123
BasicBinder:71 - binding parameter [6] as [VARCHAR] - <null>
BasicBinder:83 - binding parameter [7] as [INTEGER] - 2014
BasicBinder:83 - binding parameter [8] as [VARCHAR] - Test pub.
BasicBinder:71 - binding parameter [9] as [VARCHAR] - <null>
BasicBinder:83 - binding parameter [10] as [VARCHAR] - Test book 12
BasicBinder:83 - binding parameter [11] as [INTEGER] - 123
BasicBinder:83 - binding parameter [12] as [INTEGER] - 123
SQL:104 - delete from Book_Author where Book_Id=?
BasicBinder:83 - binding parameter [1] as [INTEGER] - 123
SQL:104 - insert into Book_Author (Book_Id, Author_Id) values (?, ?)
BasicBinder:83 - binding parameter [1] as [INTEGER] - 123
BasicBinder:83 - binding parameter [2] as [INTEGER] - 147
SQL:104 - insert into Book_Author (Book_Id, Author_Id) values (?, ?)
BasicBinder:83 - binding parameter [1] as [INTEGER] - 123
BasicBinder:83 - binding parameter [2] as [INTEGER] - 147
SqlExceptionHelper:143 - SQL Error: 1062, SQLState: 23000
SqlExceptionHelper:144 - Duplicate entry '123-147' for key 'PRIMARY'
GenericDaoImpl:100 - Update operation FAILED org.hibernate.exception.ConstraintViolationException: Duplicate entry '123-147' for key 'PRIMARY'
HibernateFactory:133 - rolling back transaction
HibernateFactory:117 - closing session
AbstractBatchImpl:205 - HHH000010: On release of batch it still contained JDBC statements

现在可以看出第一个123,147在那里,因为在更新时我没有更改authorName,第二个是因为我在之前的请求中更改了它,这是第一次应用程序启动。

Book类如下:

package com.dao.dto;

import java.util.HashSet;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.OneToMany;
import javax.persistence.Transient;

import org.codehaus.jackson.annotate.JsonManagedReference;
import org.hibernate.annotations.Fetch;
import org.hibernate.annotations.FetchMode;
import org.springframework.web.multipart.MultipartFile;

// TODO: Auto-generated Javadoc
/**
 * The Class Book.
 */
@Entity
public class Book implements java.io.Serializable {

    /** The Constant serialVersionUID. */
    private static final long serialVersionUID = 1L;

    /** The book id. */
    private int bookId;

    /** The title. */
    private String title;

    /** The isbn. */
    private String isbn;

    /** The image. */
    private String image;

    /** The in stock. */
    private int inStock;

    /** The copies issued. */
    private int copiesIssued;

    /** The published year. */
    private int publishedYear;

    /** The publisher name. */
    private String publisherName;

    /** The description. */
    private String description;

    /** The availability. */
    private String availability;

    /** The total stock. */
    private int totalStock;

    /** The file. */
    private MultipartFile file;

    private String status;

    /** The authors. */
    private Set<Author> authors = new HashSet<Author>(0);

    /** The categories. */
    private Set<Category> categories = new HashSet<Category>(0);

    /** The languages. */
    private Set<Language> languages = new HashSet<Language>(0);

    /** The users favorite. */
    private Set<User> usersFavorite = new HashSet<User>(0);

    /** The return requests. */
    private Set<ReturnRequest> returnRequests = new HashSet<ReturnRequest>(0);

    /** The delivery requests. */
    private Set<DeliveryRequest> deliveryRequests = new HashSet<DeliveryRequest>(
            0);

    /**
     * Gets the book id.
     * 
     * @return the book id
     */
    @Id
    @GeneratedValue
    @Column(name = "Book_Id")
    public int getBookId() {
        return bookId;
    }

    /**
     * Sets the book id.
     * 
     * @param bookId
     *            the new book id
     */
    public void setBookId(int bookId) {
        this.bookId = bookId;
    }

    /**
     * Gets the title.
     * 
     * @return the title
     */
    @Column(name = "Title")
    public String getTitle() {
        return title;
    }

    /**
     * Sets the title.
     * 
     * @param title
     *            the new title
     */
    public void setTitle(String title) {
        this.title = title;
    }

    /**
     * Gets the copies issued.
     * 
     * @return the copies issued
     */
    @Column(name = "Copies_Issued")
    public int getCopiesIssued() {
        return copiesIssued;
    }

    /**
     * Sets the copies issued.
     * 
     * @param copiesIssued
     *            the new copies issued
     */
    public void setCopiesIssued(int copiesIssued) {
        this.copiesIssued = copiesIssued;
    }



    public String getStatus() {
        return status;
    }

    public void setStatus(String status) {
        this.status = status;
    }

    /**
     * Gets the isbn.
     * 
     * @return the isbn
     */
    @Column(name = "Isbn")
    public String getIsbn() {
        return isbn;
    }

    /**
     * Sets the isbn.
     * 
     * @param isbn
     *            the new isbn
     */
    public void setIsbn(String isbn) {
        this.isbn = isbn;
    }

    /**
     * Gets the image.
     * 
     * @return the image
     */
    @Column(name = "Image")
    public String getImage() {
        return image;
    }

    /**
     * Sets the image.
     * 
     * @param image
     *            the new image
     */
    public void setImage(String image) {
        this.image = image;
    }

    /**
     * Gets the in stock.
     * 
     * @return the in stock
     */
    @Column(name = "In_Stock")
    public int getInStock() {
        return inStock;
    }

    /**
     * Sets the in stock.
     * 
     * @param inStock
     *            the new in stock
     */
    public void setInStock(int inStock) {
        this.inStock = inStock;
    }

    /**
     * Gets the total stock.
     * 
     * @return the total stock
     */
    @Column(name = "Total_Stock")
    public int getTotalStock() {
        return totalStock;
    }

    /**
     * Sets the total stock.
     * 
     * @param totalStock
     *            the new total stock
     */
    public void setTotalStock(int totalStock) {
        this.totalStock = totalStock;
    }

    /**
     * Gets the published year.
     * 
     * @return the published year
     */
    @Column(name = "Published_Year")
    public int getPublishedYear() {
        return publishedYear;
    }

    /**
     * Sets the published year.
     * 
     * @param publishedYear
     *            the new published year
     */
    public void setPublishedYear(int publishedYear) {
        this.publishedYear = publishedYear;
    }

    /**
     * Gets the publisher name.
     * 
     * @return the publisher name
     */
    @Column(name = "Publisher_Name")
    public String getPublisherName() {
        return publisherName;
    }

    /**
     * Sets the publisher name.
     * 
     * @param publisherName
     *            the new publisher name
     */
    public void setPublisherName(String publisherName) {
        this.publisherName = publisherName;
    }

    /**
     * Gets the description.
     * 
     * @return the description
     */
    @Column(name = "Description")
    public String getDescription() {
        return description;
    }

    /**
     * Sets the description.
     * 
     * @param description
     *            the new description
     */
    public void setDescription(String description) {
        this.description = description;
    }

    /**
     * Gets the availability.
     * 
     * @return the availability
     */
    @Column(name = "Availability")
    public String getAvailability() {
        return availability;
    }

    /**
     * Sets the availability.
     * 
     * @param availability
     *            the new availability
     */
    public void setAvailability(String availability) {
        this.availability = availability;
    }

    /**
     * Gets the authors.
     * 
     * @return the authors
     */
    @JsonManagedReference
    @ManyToMany(fetch = FetchType.EAGER)
    @JoinTable(name = "Book_Author", joinColumns = { @JoinColumn(name = "Book_Id", nullable = false) }, inverseJoinColumns = { @JoinColumn(name = "Author_Id", nullable = false) })
    public Set<Author> getAuthors() {
        return authors;
    }

    /**
     * Sets the authors.
     * 
     * @param authors
     *            the new authors
     */
    public void setAuthors(Set<Author> authors) {
        this.authors = authors;
    }

    /**
     * Gets the categories.
     * 
     * @return the categories
     */
    @JsonManagedReference
    @ManyToMany(fetch = FetchType.EAGER)
    @JoinTable(name = "Book_Category", joinColumns = { @JoinColumn(name = "Book_Id", nullable = false) }, inverseJoinColumns = { @JoinColumn(name = "Category_Id", nullable = false) })
    public Set<Category> getCategories() {
        return categories;
    }

    /**
     * Sets the categories.
     * 
     * @param categories
     *            the new categories
     */
    public void setCategories(Set<Category> categories) {
        this.categories = categories;
    }

    /**
     * Gets the languages.
     * 
     * @return the languages
     */
    @ManyToMany(fetch = FetchType.EAGER)
    @JoinTable(name = "Book_Language", joinColumns = { @JoinColumn(name = "Book_Id", nullable = false) }, inverseJoinColumns = { @JoinColumn(name = "Language_Id", nullable = false) })
    public Set<Language> getLanguages() {
        return languages;
    }

    /**
     * Sets the languages.
     * 
     * @param languages
     *            the new languages
     */
    public void setLanguages(Set<Language> languages) {
        this.languages = languages;
    }

    /**
     * Gets the users favorite.
     * 
     * @return the users favorite
     */
    @ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    @JoinTable(name = "User_Favorite", joinColumns = { @JoinColumn(name = "Book_Id", nullable = false) }, inverseJoinColumns = { @JoinColumn(name = "User_Id", nullable = false) })
    public Set<User> getUsersFavorite() {
        return usersFavorite;
    }

    /**
     * Sets the users favorite.
     * 
     * @param usersFavorite
     *            the new users favorite
     */
    public void setUsersFavorite(Set<User> usersFavorite) {
        this.usersFavorite = usersFavorite;
    }

    /**
     * Gets the file.
     * 
     * @return the file
     */
    @Transient
    public MultipartFile getFile() {
        return file;
    }

    /**
     * Sets the file.
     * 
     * @param file
     *            the new file
     */
    public void setFile(MultipartFile file) {
        this.file = file;
    }

    /*
     * (non-Javadoc)
     * 
     * @see java.lang.Object#toString()
     */
    @Override
    public String toString() {
        return getTitle();
    }

    /**
     * Gets the return requests.
     * 
     * @return the return requests
     */
    @OneToMany(fetch = FetchType.EAGER, mappedBy = "book")
    public Set<ReturnRequest> getReturnRequests() {
        return returnRequests;
    }

    /**
     * Sets the return requests.
     * 
     * @param returnRequests
     *            the new return requests
     */
    public void setReturnRequests(Set<ReturnRequest> returnRequests) {
        this.returnRequests = returnRequests;
    }

    /**
     * Gets the delivery requests.
     * 
     * @return the delivery requests
     */
    @OneToMany(fetch = FetchType.EAGER, mappedBy = "book")
    public Set<DeliveryRequest> getDeliveryRequests() {
        return deliveryRequests;
    }

    /**
     * Sets the delivery requests.
     * 
     * @param deliveryRequests
     *            the new delivery requests
     */
    public void setDeliveryRequests(Set<DeliveryRequest> deliveryRequests) {
        this.deliveryRequests = deliveryRequests;
    }

    /*
     * (non-Javadoc)
     * 
     * @see java.lang.Object#hashCode()
     */
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + bookId;
        return result;
    }

    /*
     * (non-Javadoc)
     * 
     * @see java.lang.Object#equals(java.lang.Object)
     */
    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        Book other = (Book) obj;
        if (bookId != other.bookId) {
            return false;
        }
        return true;
    }

}

作者类如下:

package com.dao.dto;

import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;

import org.codehaus.jackson.annotate.JsonBackReference;
import org.hamcrest.Factory;
import org.hibernate.annotations.Fetch;
import org.hibernate.annotations.FetchMode;

// TODO: Auto-generated Javadoc
/**
 * The Class Author.
 */
@Entity
@Table(name = "Author")
public class Author implements Serializable {

    /** The Constant serialVersionUID. */
    private static final long serialVersionUID = 1L;

    /** The author id. */
    private int authorId;

    /** The author name. */
    private String authorName;

    /** The description. */
    private String description;

    /** The books. */
    private Set<Book> books = new HashSet<Book>(0);

    /**
     * Gets the author id.
     * 
     * @return the author id
     */
    @Id
    @GeneratedValue
    @Column(name = "Author_Id")
    public int getAuthorId() {
        return authorId;
    }

    /**
     * Sets the author id.
     * 
     * @param authorId
     *            the new author id
     */
    public void setAuthorId(int authorId) {
        this.authorId = authorId;
    }

    /**
     * Gets the author name.
     * 
     * @return the author name
     */
    @Column(name = "Author_Name", nullable = false)
    public String getAuthorName() {
        return authorName;
    }

    /**
     * Sets the author name.
     * 
     * @param authorName
     *            the new author name
     */
    public void setAuthorName(String authorName) {
        this.authorName = authorName;
    }

    /**
     * Gets the description.
     * 
     * @return the description
     */
    @Column(name = "Description")
    public String getDescription() {
        return description;
    }

    /**
     * Sets the description.
     * 
     * @param description
     *            the new description
     */
    public void setDescription(String description) {
        this.description = description;
    }

    /*
     * (non-Javadoc)
     * 
     * @see java.lang.Object#toString()
     */
    public String toString() {
        return getAuthorName();
    }

    /**
     * Gets the books.
     * 
     * @return the books
     */
    @JsonBackReference
    @ManyToMany(mappedBy ="authors" ,fetch = FetchType.LAZY)
    public Set<Book> getBooks() {
        return books;
    }

    /**
     * Sets the books.
     * 
     * @param books
     *            the new books
     */
    public void setBooks(Set<Book> books) {
        this.books = books;
    }

}

最初我收到了NonUniqueObjectException,我通过删除级联删除了它。现在我被困在这一个。请注意,解释此错误的原因。谢谢。

1 个答案:

答案 0 :(得分:0)

这是因为它试图用相同的ID保存新条目。为什么不在执行保存之前删除上一个条目并添加具有相同ID的新条目。