首先让我说,我不是 Java 程序员,但我正在尝试学习一些新的(对我而言)东西。
我有以下两个 DAO: 货架
package org.sample.bookshelf.model;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.OneToMany;
import javax.persistence.Table;
@Entity
@Table(name="shelves")
public class Shelf {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Long id;
private String name;
@OneToMany(cascade=CascadeType.ALL)
@JoinTable(name="shelf_books",
joinColumns = {@JoinColumn(name="shelf_id", referencedColumnName="id")},
inverseJoinColumns = {@JoinColumn(name="book_id", referencedColumnName="id")}
)
private Set<Book> shelfBooks;
public Shelf() {}
public Shelf(String name) {
this.name = name;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Set<Book> getShelfBooks() {
return shelfBooks;
}
public void setShelfBooks(Set<Book> shelfBooks) {
this.shelfBooks = shelfBooks;
}
}
和书
package org.sample.bookshelf.model;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.OneToOne;
import javax.persistence.Table;
@Entity
@Table(name="books")
public class Book {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Long id;
private String title;
@OneToOne(cascade=CascadeType.ALL)
@JoinTable(name="shelf_books",
joinColumns = {@JoinColumn(name="book_id", referencedColumnName="id")},
inverseJoinColumns = {@JoinColumn(name="shelf_id", referencedColumnName="id")}
)
private Shelf block;
public Book() {
}
public Book(String title)
{
this.title = title;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public Shelf getShelf() {
return block;
}
public void setShelf(Shelf block) {
this.block = block;
}
}
如您所见,它们是按表关联的:*shelf_books*
现在在BookDaoImpl中,我想拥有一种全有或全无行为的方法,这可以让我保存多本书,如下所示:
@Override
public void saveMulti(List<Book> books) {
Session sess = sessionFactory.openSession();
org.hibernate.Transaction tx = null;
try {
tx = sess.beginTransaction();
int i = 0;
for (Book b : books) {
logger.debug(String.format("%d %s ", b.getId(), b.getTitle()));
sess.saveOrUpdate(b);
i++;
if (i == 20) {
sess.flush();
sess.clear();
i = 0;
}
}
logger.debug("saving...");
tx.commit();
logger.debug("done...");
} catch (RuntimeException e) {
if (tx != null) tx.rollback();
e.printStackTrace();
} finally {
sess.close();
}
}
由于某种原因,关联表的数据是添加而不是删除,它在包含删除集合 org.sample.bookshelf.model.Shelf.shelfBooks的以下日志中可见:
16:08:13,857 DEBUG BookDaoImpl:58 - saving...
16:08:13,857 DEBUG AbstractTransactionImpl:175 - committing
16:08:13,857 DEBUG AbstractFlushingEventListener:149 - Processing flush-time cascades
16:08:13,857 DEBUG AbstractFlushingEventListener:189 - Dirty checking collections
16:08:13,859 DEBUG AbstractFlushingEventListener:123 - Flushed: 0 insertions, 1 updates, 0 deletions to 11 objects
16:08:13,859 DEBUG AbstractFlushingEventListener:130 - Flushed: 0 (re)creations, 0 updates, 1 removals to 0 collections
16:08:13,859 DEBUG EntityPrinter:114 - Listing entities:
16:08:13,860 DEBUG EntityPrinter:121 - org.sample.bookshelf.model.Book{id=2, title=The City of the Sun, block=org.sample.bookshelf.model.Shelf#1}
16:08:13,860 DEBUG EntityPrinter:121 - org.sample.bookshelf.model.Shelf{id=1, shelfBooks=null, name=dystopia}
16:08:13,860 DEBUG EntityPrinter:121 - org.sample.bookshelf.model.Book{id=1, title=1984, block=org.sample.bookshelf.model.Shelf#1}
16:08:13,860 DEBUG EntityPrinter:121 - org.sample.bookshelf.model.Book{id=6, title=Logan's Run, block=org.sample.bookshelf.model.Shelf#1}
16:08:13,860 DEBUG EntityPrinter:121 - org.sample.bookshelf.model.Book{id=5, title=Slaughterhouse Five, block=org.sample.bookshelf.model.Shelf#1}
16:08:13,860 DEBUG EntityPrinter:121 - org.sample.bookshelf.model.Book{id=4, title=Fahrenheit 451, block=org.sample.bookshelf.model.Shelf#1}
16:08:13,861 DEBUG EntityPrinter:121 - org.sample.bookshelf.model.Book{id=3, title=The Honeymoon Trip of Mr. Hamilton, block=org.sample.bookshelf.model.Shelf#1}
16:08:13,861 DEBUG EntityPrinter:121 - org.sample.bookshelf.model.Book{id=10, title=Brave New World, block=org.sample.bookshelf.model.Shelf#1}
16:08:13,861 DEBUG EntityPrinter:121 - org.sample.bookshelf.model.Book{id=9, title=Lord of the Flies, block=org.sample.bookshelf.model.Shelf#1}
16:08:13,861 DEBUG EntityPrinter:121 - org.sample.bookshelf.model.Book{id=8, title=Do Androids Dream of Electric Sheep?, block=org.sample.bookshelf.model.Shelf#1}
16:08:13,861 DEBUG EntityPrinter:121 - org.sample.bookshelf.model.Book{id=7, title=The Futurological Congress, block=org.sample.bookshelf.model.Shelf#1}
16:08:13,867 DEBUG SQL:109 - /* update org.sample.bookshelf.model.Shelf */ update shelves set name=? where id=?
16:08:13,869 DEBUG AbstractCollectionPersister:1174 - Deleting collection: [org.sample.bookshelf.model.Shelf.shelfBooks#1]
16:08:13,869 DEBUG SQL:109 - /* delete collection org.sample.bookshelf.model.Shelf.shelfBooks */ delete from shelf_books where shelf_id=?
16:08:13,870 DEBUG AbstractCollectionPersister:1232 - Done deleting collection
16:08:14,199 DEBUG JdbcTransaction:113 - committed JDBC Connection
16:08:14,199 DEBUG JdbcTransaction:126 - re-enabling autocommit
16:08:14,200 DEBUG BookDaoImpl:60 - done...
我猜出于某种原因,书架不知道添加的书籍,为了使其完整,这就是我添加数据的方式:
String titles[] = {
"1984",
"The City of the Sun",
"The Honeymoon Trip of Mr. Hamilton",
"Fahrenheit 451",
"Slaughterhouse Five",
"Logan's Run",
"The Futurological Congress",
"Do Androids Dream of Electric Sheep?",
"Lord of the Flies",
"Brave New World",
};
Vector<Book> books = new Vector<Book>(titles.length);
for (int i=0; i<titles.length; ++i) {
Book book = new Book(titles[i]);
book.setShelf(shelf);
books.add(book);
}
bookDao.saveMulti(books);
如您所见,我没有在任何地方调用shelf.setShelfBooks,如果我这样做,一切似乎都很好,但是hibernate的作用看起来很糟糕,请查看以下日志的片段:
16:20:15,015 DEBUG EntityPrinter:121 - org.sample.bookshelf.model.Book{id=8, title=Do Androids Dream of Electric Sheep?, block=org.sample.bookshelf.model.Shelf#1}
16:20:15,015 DEBUG EntityPrinter:121 - org.sample.bookshelf.model.Book{id=7, title=Fahrenheit 451, block=org.sample.bookshelf.model.Shelf#1}
16:20:15,021 DEBUG SQL:109 - /* update org.sample.bookshelf.model.Shelf */ update shelves set name=? where id=?
16:20:15,023 DEBUG AbstractCollectionPersister:1174 - Deleting collection: [org.sample.bookshelf.model.Shelf.shelfBooks#1]
16:20:15,023 DEBUG SQL:109 - /* delete collection org.sample.bookshelf.model.Shelf.shelfBooks */ delete from shelf_books where shelf_id=?
16:20:15,026 DEBUG AbstractCollectionPersister:1232 - Done deleting collection
16:20:15,027 DEBUG AbstractCollectionPersister:1256 - Inserting collection: [org.sample.bookshelf.model.Shelf.shelfBooks#1]
16:20:15,028 DEBUG SQL:109 - /* insert collection row org.sample.bookshelf.model.Shelf.shelfBooks */ insert into shelf_books (shelf_id, book_id) values (?, ?)
16:20:15,030 DEBUG SQL:109 - /* insert collection row org.sample.bookshelf.model.Shelf.shelfBooks */ insert into shelf_books (shelf_id, book_id) values (?, ?)
16:20:15,030 DEBUG SQL:109 - /* insert collection row org.sample.bookshelf.model.Shelf.shelfBooks */ insert into shelf_books (shelf_id, book_id) values (?, ?)
我有感觉,我做错了,谁能告诉我什么应该是正确的方法来做我想做的事?