我有一个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,我通过删除级联删除了它。现在我被困在这一个。请注意,解释此错误的原因。谢谢。
答案 0 :(得分:0)
这是因为它试图用相同的ID保存新条目。为什么不在执行保存之前删除上一个条目并添加具有相同ID的新条目。