java - What is the difference between enitityManager.find and entityManager.createQuery? -
ok, using ejb 3.0 hibernate, dropped our .ear file easy-beans 1.0.1 (with hibernate) deploy directory embedded apache tomcat 6.0.18. database had persist things this:
@entity @table(name="author") public class author implements serializable { ////////////////////////////////////////////////////////////////// // fields ////////////////////////////////////////////////////////////////// @id @generatedvalue(strategy = identity) @column(name = "a_id", unique=true, nullable = false) private integer id; @column (name = "a_name", unique = false, nullable = false) private string name; @column (name = "a_lastname", unique = false, nullable = false) private string lastname; @onetomany(cascade = {all}, fetch = eager, mappedby = "author") private set<bookauthor> bookauthors = new hashset<bookauthor>(); @override public boolean equals(object o) { if (this == o) return true; if (o == null || getclass() != o.getclass()) return false; author author = (author) o; if (id != null ? !id.equals(author.id) : author.id != null) return false; return true; } @override public int hashcode() { return id != null ? id.hashcode() : 0; } } @entity @table(name = "book" ) public class book implements serializable { ////////////////////////////////////////////////////////////////// // fields ////////////////////////////////////////////////////////////////// @id @generatedvalue (strategy = identity) @column(name = "b_id", unique = true, nullable = false) private integer bid; @column(name = "b_year", unique = false, nullable = true) private integer year; @column(name = "b_isbn", unique = false, nullable = false) private string isbn; @column(name = "b_title", unique = false, nullable = false) private string title; @onetomany(cascade = {all}, fetch = eager, mappedby = "book") private set<bookauthor> bookauthors = new hashset<bookauthor>(); @override public boolean equals(object o) { if (this == o) return true; if (o == null || getclass() != o.getclass()) return false; book book = (book) o; if (isbn != null ? !isbn.equals(book.isbn) : book.isbn != null) return false; if (bid != null ? !kid.equals(book.bid) : book.bid != null) return false; return true; } @override public int hashcode() { int result = bid != null ? bid.hashcode() : 0; result = 31 * result + (isbn != null ? isbn.hashcode() : 0); return result; } } @entity @table(name = "book_author") public class bookauthor implements serializable { ////////////////////////////////////////////////////////////////// // fields ////////////////////////////////////////////////////////////////// @id @generatedvalue(strategy = identity) @column(name = "ba_id", unique=true, nullable = false) private integer id; @column(name = "ba_role", unique = false, nullable = true) private string role; @manytoone @joincolumn (name = "a_id", referencedcolumnname = "a_id", nullable = false) private author author; @manytoone @joincolumn (name = "b_id", referencedcolumnname = "b_id", nullable = false) private book book; @override public boolean equals(object o) { if (this == o) return true; if (o == null || getclass() != o.getclass()) return false; bookauthor = (bookauthor) o; if (auhtor != null ? !author.equals(that.author) : that.author != null) return false; if (book != null ? !book.equals(that.book) : that.book!= null) return false; if (id != null ? !id.equals(that.id) : that.id != null) return false; return true; } @override public int hashcode() { int result = id != null ? id.hashcode() : 0; result = 31 * result + (author != null ? author.hashcode() : 0); result = 31 * result + (book != null ? book.hashcode() : 0); return result; } }
so when removing items had entity bean went this:
@stateless @local(deletebookauthor.class) public class deletebookauthorbean implements deletebookauthor { @persistencecontext(unitname="library") protected entitymanager em; @override public void removebyid(integer id) { try{ query q = em.createquery("select ba bookauthor ba id = ?1"); q.setparameter(1,id); bookauthor ba = (bookauthor) q.getsingleresult(); ba.getauthor().getbookauthors().remove(ba); ba.getbook().getbookauthors().remove(ba); em.remove(ba); }catch (exception e){ e.printstacktrace(); } } }
unfortunatelly, when servlet calls bean returns "deleted entity passed persist" exception; changing lines:
query q = em.createquery("select ba bookauthor ba id = ?1"); q.setparameter(1,id); bookauthor ba = (bookauthor) q.getsingleresult();
to
bookauthor ba = em.find(bookauthor.class, id)
makes problem go away. question ask why? in similar situation used em.createquery
retrieve , delete muliple entities , worked without hitch. why won't work now?
update: calling query q=...
, removing bookauthors removes bookauthors
books
not authors
. in second case removed both sets. both ba
have same hash , return true
when compared using baquery.equals(bafind)
.
any clarifications why 2 functions return same object calling remove
behave differently depending on whether query
/find
called?
perhaps it's related lack of equals()
/hashcode()
in bookauthor
. if so, looks in case of query have several different instances of bookauthor
same state, not removed corresponding sets in author
, book
.
Comments
Post a Comment