Ok. I have this collection which implemented using a mapping/association table. This table has an extra column which stores the order of the associated objects.
I have a problem with hibernate always thinking my collection is dirty and deleting it and reinserting it. This happens every time I attempt to
load the object. So, when I load Chapter where id=1 the set of pages is loaded, determined to be dirty, deleted from the association table, reinserted into the association table, and reinserted into the object.
I've looked at:
http://www.hibernate.org/116.html#A15 the object's getter/setter methods are as simple as they can get.
Any help anyone could offer would be exceptional. I'm at my wits end.
Here is the output from the log:
Code:
NFO - Loading the object from the db based on param.id:1
DEBUG - Opening Hibernate Session
DEBUG - opened session at timestamp: 4761563160371200
DEBUG - loading entity: [com.hdms.rdesigner.domain.chapter.Chapter#1]
DEBUG - attempting to resolve: [com.hdms.rdesigner.domain.chapter.Chapter#1]
DEBUG - object not resolved in any cache: [com.hdms.rdesigner.domain.chapter.Chapter#1]
DEBUG - Fetching entity: [com.hdms.rdesigner.domain.chapter.Chapter#1]
DEBUG - loading entity: [com.hdms.rdesigner.domain.chapter.Chapter#1]
DEBUG - about to open PreparedStatement (open PreparedStatements: 0, globally: 0)
DEBUG - opening JDBC connection
[b]DEBUG - /* load com.hdms.rdesigner.domain.chapter.Chapter [/b]*/ select chapter0_.id as id0_0_, chapter0_.name as name0_0_, chapter0_.shortName as shortName0_0_, chapter0_.description as descript4_0_0_ from Chapters chapter0_ where chapter0_.id=?
DEBUG - preparing statement
DEBUG - binding '1' to parameter: 1
DEBUG - about to open ResultSet (open ResultSets: 0, globally: 0)
DEBUG - processing result set
DEBUG - result set row: 0
DEBUG - result row: EntityKey[com.hdms.rdesigner.domain.chapter.Chapter#1]
DEBUG - Initializing object from ResultSet: [com.hdms.rdesigner.domain.chapter.Chapter#1]
DEBUG - Hydrating entity: [com.hdms.rdesigner.domain.chapter.Chapter#1]
DEBUG - returning 'a' as column: name0_0_
DEBUG - returning 'a' as column: shortName0_0_
DEBUG - returning '' as column: descript4_0_0_
DEBUG - done processing result set (1 rows)
DEBUG - about to close ResultSet (open ResultSets: 1, globally: 1)
DEBUG - about to close PreparedStatement (open PreparedStatements: 1, globally: 1)
DEBUG - closing statement
DEBUG - total objects hydrated: 1
DEBUG - resolving associations for [com.hdms.rdesigner.domain.chapter.Chapter#1]
DEBUG - creating collection wrapper:[com.hdms.rdesigner.domain.chapter.Chapter.pages#1]
DEBUG - initializing collection [com.hdms.rdesigner.domain.chapter.Chapter.pages#1]
DEBUG - checking second-level cache
DEBUG - collection not cached
DEBUG - loading collection: [com.hdms.rdesigner.domain.chapter.Chapter.pages#1]
DEBUG - about to open PreparedStatement (open PreparedStatements: 0, globally: 0)
DEBUG - /* load collection com.hdms.rdesigner.domain.chapter.Chapter.pages */ select pages0_.ChapterId as ChapterId1_, pages0_.PageOrder as PageOrder1_, pages0_.pageId as pageId1_, page1_.id as id6_0_, page1_.name as name6_0_, page1_.shortName as shortName6_0_, page1_.description as descript4_6_0_ from ChapterPageMap pages0_ inner join Pages page1_ on pages0_.pageId=page1_.id where pages0_.ChapterId=? order by pages0_.PageOrder
DEBUG - preparing statement
DEBUG - binding '1' to parameter: 1
DEBUG - about to open ResultSet (open ResultSets: 0, globally: 0)
DEBUG - result set contains (possibly empty) collection: [com.hdms.rdesigner.domain.chapter.Chapter.pages#1]
DEBUG - uninitialized collection: initializing
DEBUG - processing result set
DEBUG - result set row: 0
DEBUG - returning '2' as column: id6_0_
DEBUG - result row: EntityKey[com.hdms.rdesigner.domain.page.Page#2]
DEBUG - Initializing object from ResultSet: [com.hdms.rdesigner.domain.page.Page#2]
DEBUG - Hydrating entity: [com.hdms.rdesigner.domain.page.Page#2]
DEBUG - returning 'b' as column: name6_0_
DEBUG - returning 'b' as column: shortName6_0_
DEBUG - returning 'a' as column: descript4_6_0_
DEBUG - returning '1' as column: ChapterId1_
DEBUG - found row of collection: [com.hdms.rdesigner.domain.chapter.Chapter.pages#1]
DEBUG - reading row
DEBUG - returning '1' as column: PageOrder1_
DEBUG - returning '2' as column: pageId1_
DEBUG - loading entity: [com.hdms.rdesigner.domain.page.Page#2]
DEBUG - attempting to resolve: [com.hdms.rdesigner.domain.page.Page#2]
DEBUG - resolved object in session cache: [com.hdms.rdesigner.domain.page.Page#2]
DEBUG - done processing result set (1 rows)
DEBUG - about to close ResultSet (open ResultSets: 1, globally: 1)
DEBUG - about to close PreparedStatement (open PreparedStatements: 1, globally: 1)
DEBUG - closing statement
DEBUG - total objects hydrated: 1
DEBUG - resolving associations for [com.hdms.rdesigner.domain.page.Page#2]
DEBUG - done materializing entity [com.hdms.rdesigner.domain.page.Page#2]
DEBUG - 1 collections were found in result set for role: com.hdms.rdesigner.domain.chapter.Chapter.pages
DEBUG - collection fully initialized: [com.hdms.rdesigner.domain.chapter.Chapter.pages#1]
DEBUG - 1 collections initialized for role: com.hdms.rdesigner.domain.chapter.Chapter.pages
DEBUG - done loading collection
DEBUG - collection initialized
DEBUG - done materializing entity [com.hdms.rdesigner.domain.chapter.Chapter#1]
DEBUG - initializing non-lazy collections
DEBUG - done entity load
DEBUG - after autocommit
DEBUG - transaction completed on session with on_close connection release mode; be sure to close the session to release JDBC resources!
DEBUG - after transaction completion
DEBUG - Eagerly flushing Hibernate session
DEBUG - flushing session
DEBUG - processing flush-time cascades
[b]DEBUG - dirty checking collections
DEBUG - Collection dirty: [com.hdms.rdesigner.domain.chapter.Chapter.pages#1][/b]
DEBUG - Flushing entities and processing referenced collections
DEBUG - Wrapped collection in role: com.hdms.rdesigner.domain.chapter.Chapter.pages
DEBUG - Collection found: [com.hdms.rdesigner.domain.chapter.Chapter.pages#1], was: [<unreferenced>] (initialized)
DEBUG - Processing unreferenced collections
DEBUG - Collection dereferenced: [com.hdms.rdesigner.domain.chapter.Chapter.pages#1]
DEBUG - Scheduling collection removes/(re)creates/updates
DEBUG - Flushed: 0 insertions, 0 updates, 0 deletions to 2 objects
DEBUG - Flushed: 1 (re)creations, 0 updates, 1 removals to 2 collections
DEBUG - listing entities:
DEBUG - com.hdms.rdesigner.domain.chapter.Chapter{pages=[component[order,page]{page=com.hdms.rdesigner.domain.page.Page#2, order=1}], shortName=a, description=, name=a, id=1}
DEBUG - com.hdms.rdesigner.domain.page.Page{shortName=b, description=a, name=b, id=2}
DEBUG - executing flush
DEBUG - registering flush begin
DEBUG - Deleting collection: [com.hdms.rdesigner.domain.chapter.Chapter.pages#1]
DEBUG - about to open PreparedStatement (open PreparedStatements: 0, globally: 0)
[b]DEBUG - /* delete collection com.hdms.rdesigner.domain.chapter.Chapter.pages */ delete from ChapterPageMap where ChapterId=?[/b]DEBUG - preparing statement
DEBUG - binding '1' to parameter: 1
DEBUG - Adding to batch
DEBUG - done deleting collection
DEBUG - Executing batch size: 1
DEBUG - about to close PreparedStatement (open PreparedStatements: 1, globally: 1)
DEBUG - closing statement
DEBUG - Inserting collection: [com.hdms.rdesigner.domain.chapter.Chapter.pages#1]
DEBUG - about to open PreparedStatement (open PreparedStatements: 0, globally: 0)
[b]DEBUG - /* insert collection row com.hdms.rdesigner.domain.chapter.Chapter.pages */ insert into ChapterPageMap (ChapterId, PageOrder, pageId) values (?, ?, ?)[/b]DEBUG - preparing statement
DEBUG - binding '1' to parameter: 1
DEBUG - binding '1' to parameter: 2
DEBUG - binding '2' to parameter: 3
DEBUG - Adding to batch
DEBUG - done inserting collection: 1 rows inserted
DEBUG - Executing batch size: 1
DEBUG - about to close PreparedStatement (open PreparedStatements: 1, globally: 1)
DEBUG - closing statement
DEBUG - registering flush end
DEBUG - post flush
DEBUG - Closing Hibernate Session
Here's my Entity/Object Hibernate mapping
Code:
<class name="com.hdms.rdesigner.domain.chapter.Chapter" table="Chapters"
lazy="false" dynamic-update="true">
<id name="id" type="long" unsaved-value="null">
<generator class="native" />
</id>
<property name="name" />
<property name="shortName" />
<property name="description" />
<set name="pages" table="ChapterPageMap" lazy="false" cascade="none" order-by="PageOrder">
<key column="ChapterId"/>
<composite-element class="com.hdms.rdesigner.domain.chapterpage.ChapterPage">
<property name="order" column="PageOrder" type="long" />
<many-to-one name="page" column="pageId" class="com.hdms.rdesigner.domain.page.Page" not-null="true"/>
</composite-element>
</set>
</class>
My Java Class File looks like:
Code:
public class Chapter extends AbstractPlanRelationshipBean{
protected Set<Packet> packets;
protected Set<Page> pages;
//For hibernate...
public Chapter() {}
public Chapter(ChapterForm form) {
id = form.getId();
name = form.getName();
shortName = form.getShortName();
description = form.getDescription();
plan = form.getPlan();
pages = form.getPages();
}
/*-------------------------------*/
public Set<Packet> getPackets() {
return packets;
}
public void setPackets(Set<Packet> val) {
packets = val;
}
public void addPacket(Packet val) {
packets.add(val);
}
/*-------------------------------*/
public Set<Page> getPages() {
return pages;
}
public void setPages(Collection <Page> val) {
pages = new LinkedHashSet(val);
}
public void addPage(Page val) {
pages.add(val);
}
/*-------------------------------*/
public void setOrderOfSets() {
//We only care about the pages
Iterator it = getPages().iterator();
for(int i=1; it.hasNext(); i++) {
Page p = (Page)it.next();
p.setOrder(new Long(i));
}
}
/*-------------------------------*/
public String toString() {
String result = super.toString();
if( packets != null) {
result += " Packets Size: " + packets.size();
}
if( pages != null) {
result += " Pages Size: " + pages.size();
}
return result;
}
}
The Table Structure is as follows:
Code:
DROP TABLE IF EXISTS ChapterPageMap ;
CREATE TABLE ChapterPageMap
(
Id INTEGER NOT NULL AUTO_INCREMENT,
ChapterId INTEGER NOT NULL REFERENCES Chapters(Id),
PageId INTEGER NOT NULL REFERENCES Pages(Id),
PageOrder INTEGER,
LastEdited TIMESTAMP,
UNIQUE INDEX1 (ChapterId, PageId),
PRIMARY KEY (Id)
)ENGINE=InnoDB;