Я опробовал в своем приложении отображение гибернации для классов доменов - Book, Author и Publisher. Я хотел удалить Publisher или Author, у которых нет Books.So, я кодировал логику добавления / удаления книги, как показано ниже.
При удалении книги проверяется размер набора книг в Author и Publisher. Если они содержат только один экземпляр книги (который будет удален), то Author и Publisher удаляются.удалены из их наборов книг.
В моей программе я поместил кодовый блок для проверки размера Set и удаления Author перед размером Publisher, как показано во фрагменте.
Когда я удаляю все книгиавтора удаляется успешно. Но издатель удаления вызывает исключение StaleStateException.Фактическое отслеживание ошибок дается в конце. Теперь, в качестве последнего усилия, я поменял блоки кода, которые удаляют Publisher и Author, и поместил deletePublisher (publisher) перед блоком, содержащим deleteAuthor (author). Теперь Publisher получаетудалено, но удаление Author вызывает StaleStateException.
Я не мог понять, была ли какая-то проблема в моей логике. Попытка регистрации и обнаружение, что в моем методе GenericDao.delete (Object obj), исключение происходит непосредственно передПроизошла транзакция и произошел откат. Я также перечислил соответствующие части кода реализации Dao.
Если кто-то может помочь ... пожалуйста, скажите мне, как я могу решить эту ошибку.
спасибо
mark
public class Book {
private Long book_id;
private String name;
private Author author;
private Publisher publisher;
...
}
public class Author {
private Long author_id;
private String name;
private Set<Book> books;
public Author() {
super();
books = new HashSet<Book>();
}
...
}
public class Publisher {
private Long publisher_id;
private String name;
private Set<Book> books;
public Publisher() {
super();
books = new HashSet<Book>();
}
...
}
Book.hbm.xml имеет
<many-to-one name="publisher" class="Publisher" column="PUBLISHER_ID" lazy="false" cascade="save-update"/>
<many-to-one name="author" class="Author" column="AUTHOR_ID" lazy="false" cascade="save-update"/>
Author.hbm.xml
...
<set name="books" inverse="true" table="BOOK" lazy="false" order-by="BOOK_NAME asc" cascade="delete-orphan">
<key column="AUTHOR_ID" />
<one-to-many class="Book" />
</set>
Publisher.hbm.xml
<set name="books" inverse="true" table="BOOK" lazy="false" order-by="BOOK_NAME asc" cascade="delete-orphan">
<key column="PUBLISHER_ID" />
<one-to-many class="Book" />
</set>
Создание книги добавляет экземпляр книги к наборам в Author и Publisher.
doPost(HttpServletRequest request, HttpServletResponse response){
...
Book book = new Book();
...
Publisher publisher = createPublisherFromUserInput();
Author author = createAuthorFromUserInput();
...
publisher.getBooks().add(book);
author.getBooks().add(book);
bookdao.saveOrUpdateBook(book);
}
Удаление книги
doPost(HttpServletRequest request, HttpServletResponse response){
...
Book bk = bookdao.findBookById(bookId);
Publisher pub = bk.getPublisher();
Author author = bk.getAuthor();
if (author.getBooks().size()==1){
authordao.deleteAuthor(author);
}else{
author.getBooks().remove(bk);
}
if(pub.getBooks().size()==1){
publisherdao.deletePublisher(pub);
}else{
pub.getBooks().remove(bk);
}
bookdao.deleteBook(bk);
}
Реализации Dao
public class PublisherDao extends GenericDao{
@Override
public void deletePublisher(Publisher publisher) {
String name = publisher.getName();
logger.info("before delete pub="+name);
delete(publisher);
logger.info("deleted pub="+name);
}
...
}
public abstract class GenericDaoImpl{
@Override
public void delete(Object obj) {
SessionFactory factory = HibernateUtil.getSessionFactory();
Session session = factory.openSession();
Transaction tx = null;
try {
tx = session.beginTransaction();
session.delete(obj);
logger.info("after session.delete(obj)");
logger.info("delete():before tx.commit");//till here no exception
tx.commit();
} catch (HibernateException e) {
if (tx != null) {
tx.rollback();
logger.info("delete():txn rolled back");//this happens when all Books are deleted
}
throw e;
} finally {
session.close();
}
}
}
And вот след от кота
SEVERE: Servlet.service() for servlet deletebookservlet threw exception
org.hibernate.StaleStateException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1
at
...
org.hibernate.jdbc.Expectations$BasicExpectation.checkBatched(ExpectationImpl.managedFlush(SessionImpl.java:375)
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:137)
at bookstore.dao.GenericDao.delete(Unknown Source)
at bookstore.dao.PublisherDao.deletePublisher(Unknown Source)
at bookstore.servlets.MyBookDeleteServlet.doPost(Unknown Source)