Question:
When adding an element to a very large collection(Kittens), hibernate loads the whole collection before adding the new element(Kitten) to the collection when using the "getKittens().add(kitten)" method. How do I add the element to the collection without loading the whole collection?
Hibernate version:
3.0.1
Mapping documents:
Code:
<!-- Cat.hbm.xml -->
<hibernate-mapping package="javaapplication1">
<class name="Cat" table="cats" lazy="true">
<id name="id">
<generator class="native"/>
</id>
<property name="name" not-null="true"/>
<set name="kittens" inverse="true" cascade="all-delete-orphan">
<key column="mother_id"/>
<one-to-many class="Cat"/>
</set>
</class>
</hibernate-mapping>
Code:
<!-- Kitten.hbm.xml -->
<hibernate-mapping package="javaapplication1">
<class name="Kitten" table="kittens" lazy="true" batch-size="4">
<id name="id">
<generator class="native"/>
</id>
<property name="name" not-null="true"/>
<many-to-one name="mother" column="mother_id"/>
</class>
</hibernate-mapping>
Code between sessionFactory.openSession() and session.close():Code:
Transaction tx = session.beginTransaction();
Cat cat = (Cat) session.load(Cat.class, new Long(1));
Kitten kitten = new Kitten();
kitten.setName("Fluffy");
cat.addKitten(kitten); // <-- Loads all of the collection.
session.persist(kitten);
tx.commit();
Code:
// Cat.java
public void addKitten(Kitten kitten) {
kitten.setMother(this);
getKittens().add(kitten);
}
Name and version of the database you are using:
MySql 3.23.58
The generated SQL (show_sql=true):
Hibernate: select cat0_.id as id0_, cat0_.name as name0_0_ from cats cat0_ where cat0_.id=?
Hibernate: select kittens0_.mother_id as mother3___, kittens0_.id as id__, kittens0_.id as id0_, kittens0_.name as name0_0_ from cats kittens0_ where kittens0_.mother_id=? order by kittens0_.name
Hibernate: insert into kittens (name, mother_id) values (?, ?)
Debug level Hibernate log excerpt:
19:03:58,598 DEBUG SessionImpl:237 - opened session at timestamp: 4566315166097408
19:03:58,598 DEBUG JDBCTransaction:46 - begin
19:03:58,598 DEBUG AbstractBatcher:414 - opening JDBC connection
19:03:58,598 DEBUG DriverManagerConnectionProvider:93 - total checked-out connections: 0
19:03:58,598 DEBUG DriverManagerConnectionProvider:99 - using pooled JDBC connection, pool size: 0
19:03:58,598 DEBUG JDBCTransaction:50 - current autocommit status: false
19:03:58,598 DEBUG DefaultLoadEventListener:196 - loading entity: [javaapplication1.Cat#1]
19:03:58,598 DEBUG DefaultLoadEventListener:243 - creating new proxy for entity
19:03:58,608 DEBUG SessionImpl:589 - initializing proxy: [javaapplication1.Cat#1]
19:03:58,608 DEBUG DefaultLoadEventListener:325 - attempting to resolve: [javaapplication1.Cat#1]
19:03:58,608 DEBUG DefaultLoadEventListener:361 - object not resolved in any cache: [javaapplication1.Cat#1]
19:03:58,608 DEBUG BasicEntityPersister:2487 - Materializing entity: [javaapplication1.Cat#1]
19:03:58,608 DEBUG Loader:1273 - loading entity: [javaapplication1.Cat#1]
19:03:58,608 DEBUG AbstractBatcher:276 - about to open PreparedStatement (open PreparedStatements: 0, globally: 0)
Hibernate: select cat0_.id as id0_, cat0_.name as name0_0_ from cats cat0_ where cat0_.id=?
19:03:58,608 DEBUG AbstractBatcher:364 - preparing statement
19:03:58,608 DEBUG LongType:59 - binding '1' to parameter: 1
19:03:58,618 DEBUG AbstractBatcher:292 - about to open ResultSet (open ResultSets: 0, globally: 0)
19:03:58,618 DEBUG Loader:382 - processing result set
19:03:58,618 DEBUG Loader:387 - result set row: 0
19:03:58,618 DEBUG Loader:762 - result row: EntityKey[javaapplication1.Cat#1]
19:03:58,618 DEBUG Loader:912 - Initializing object from ResultSet: [javaapplication1.Cat#1]
19:03:58,618 DEBUG BasicEntityPersister:1660 - Hydrating entity: [javaapplication1.Cat#1]
19:03:58,618 DEBUG StringType:86 - returning 'Princess' as column: name0_0_
19:03:58,618 DEBUG Loader:406 - done processing result set (1 rows)
19:03:58,618 DEBUG AbstractBatcher:299 - about to close ResultSet (open ResultSets: 1, globally: 1)
19:03:58,618 DEBUG AbstractBatcher:284 - about to close PreparedStatement (open PreparedStatements: 1, globally: 1)
19:03:58,618 DEBUG AbstractBatcher:392 - closing statement
19:03:58,618 DEBUG Loader:492 - total objects hydrated: 1
19:03:58,618 DEBUG TwoPhaseLoad:96 - resolving associations for [javaapplication1.Cat#1]
19:03:58,628 DEBUG CollectionLoadContext:134 - creating collection wrapper:[javaapplication1.Cat.kittens#1]
19:03:58,628 DEBUG TwoPhaseLoad:167 - done materializing entity [javaapplication1.Cat#1]
19:03:58,628 DEBUG PersistenceContext:758 - initializing non-lazy collections
19:03:58,628 DEBUG Loader:1301 - done entity load
19:03:58,628 DEBUG DefaultInitializeCollectionEventListener:42 - initializing collection [javaapplication1.Cat.kittens#1]
19:03:58,628 DEBUG DefaultInitializeCollectionEventListener:47 - checking second-level cache
19:03:58,628 DEBUG DefaultInitializeCollectionEventListener:59 - collection not cached
19:03:58,628 DEBUG Loader:1359 - loading collection: [javaapplication1.Cat.kittens#1]
19:03:58,628 DEBUG AbstractBatcher:276 - about to open PreparedStatement (open PreparedStatements: 0, globally: 0)
Hibernate: select kittens0_.mother_id as mother3___, kittens0_.id as id__, kittens0_.id as id0_, kittens0_.name as name0_0_ from cats kittens0_ where kittens0_.mother_id=? order by kittens0_.name
19:03:58,628 DEBUG AbstractBatcher:364 - preparing statement
19:03:58,628 DEBUG LongType:59 - binding '1' to parameter: 1
19:03:58,638 DEBUG AbstractBatcher:292 - about to open ResultSet (open ResultSets: 0, globally: 0)
19:03:58,638 DEBUG Loader:653 - result set contains (possibly empty) collection: [javaapplication1.Cat.kittens#1]
19:03:58,638 DEBUG CollectionLoadContext:78 - uninitialized collection: initializing
19:03:58,638 DEBUG Loader:382 - processing result set
19:03:58,638 DEBUG Loader:406 - done processing result set (0 rows)
19:03:58,638 DEBUG AbstractBatcher:299 - about to close ResultSet (open ResultSets: 1, globally: 1)
19:03:58,638 DEBUG AbstractBatcher:284 - about to close PreparedStatement (open PreparedStatements: 1, globally: 1)
19:03:58,638 DEBUG AbstractBatcher:392 - closing statement
19:03:58,638 DEBUG Loader:492 - total objects hydrated: 0
19:03:58,638 DEBUG CollectionLoadContext:248 - 1 collections were found in result set
19:03:58,658 DEBUG CollectionLoadContext:193 - collection fully initialized: [javaapplication1.Cat.kittens#1]
19:03:58,658 DEBUG CollectionLoadContext:256 - 1 collections initialized
19:03:58,658 DEBUG PersistenceContext:758 - initializing non-lazy collections
19:03:58,658 DEBUG Loader:1383 - done loading collection
19:03:58,658 DEBUG DefaultInitializeCollectionEventListener:61 - collection initialized
19:03:58,658 DEBUG AbstractSaveEventListener:408 - transient instance of: javaapplication1.Kitten
19:03:58,658 DEBUG DefaultPersistEventListener:117 - saving transient instance
19:03:58,658 DEBUG AbstractSaveEventListener:89 - generated identifier: , using strategy: org.hibernate.id.IdentityGenerator
19:03:58,658 DEBUG AbstractSaveEventListener:132 - saving [javaapplication1.Kitten#<null>]
19:03:58,658 DEBUG AbstractSaveEventListener:193 - executing insertions
19:03:58,658 DEBUG BasicEntityPersister:1741 - Inserting entity: javaapplication1.Kitten (native id)
19:03:58,658 DEBUG AbstractBatcher:276 - about to open PreparedStatement (open PreparedStatements: 0, globally: 0)
Hibernate: insert into kittens (name, mother_id) values (?, ?)
19:03:58,658 DEBUG AbstractBatcher:364 - preparing statement
19:03:58,658 DEBUG BasicEntityPersister:1621 - Dehydrating entity: [javaapplication1.Kitten#<null>]
19:03:58,658 DEBUG StringType:59 - binding 'LastPrince' to parameter: 1
19:03:58,658 DEBUG LongType:59 - binding '1' to parameter: 2
19:03:58,668 DEBUG IdentifierGeneratorFactory:37 - Natively generated identity: 2001
19:03:58,668 DEBUG AbstractBatcher:284 - about to close PreparedStatement (open PreparedStatements: 1, globally: 1)
19:03:58,668 DEBUG AbstractBatcher:392 - closing statement
19:03:58,668 DEBUG JDBCTransaction:83 - commit
19:03:58,668 DEBUG SessionImpl:308 - automatically flushing session
19:03:58,668 DEBUG AbstractFlushingEventListener:52 - flushing session
19:03:58,668 DEBUG AbstractFlushingEventListener:102 - processing flush-time cascades
19:03:58,668 DEBUG Cascades:806 - processing cascade ACTION_SAVE_UPDATE for: javaapplication1.Cat
19:03:58,678 DEBUG Cascades:855 - cascade ACTION_SAVE_UPDATE for collection: javaapplication1.Cat.kittens
19:03:58,678 DEBUG Cascades:152 - cascading to saveOrUpdate: javaapplication1.Cat
19:03:58,678 DEBUG AbstractSaveEventListener:392 - persistent instance of: javaapplication1.Cat
19:03:58,678 DEBUG DefaultSaveOrUpdateEventListener:103 - ignoring persistent instance
19:03:58,678 DEBUG DefaultSaveOrUpdateEventListener:140 - object already associated with session: [javaapplication1.Kitten#2001]
19:03:58,678 DEBUG Cascades:873 - done cascade ACTION_SAVE_UPDATE for collection: javaapplication1.Cat.kittens
19:03:58,678 DEBUG Cascades:884 - deleting orphans for collection: javaapplication1.Cat.kittens
19:03:58,678 DEBUG Cascades:894 - done deleting orphans for collection: javaapplication1.Cat.kittens
19:03:58,678 DEBUG Cascades:831 - done processing cascade ACTION_SAVE_UPDATE for: javaapplication1.Cat
19:03:58,678 DEBUG AbstractFlushingEventListener:150 - dirty checking collections
19:03:58,678 DEBUG CollectionEntry:115 - Collection dirty: [javaapplication1.Cat.kittens#1]
19:03:58,678 DEBUG AbstractFlushingEventListener:167 - Flushing entities and processing referenced collections
19:03:58,678 DEBUG Collections:140 - Collection found: [javaapplication1.Cat.kittens#1], was: [javaapplication1.Cat.kittens#1] (initialized)
19:03:58,678 DEBUG AbstractFlushingEventListener:203 - Processing unreferenced collections
19:03:58,678 DEBUG AbstractFlushingEventListener:217 - Scheduling collection removes/(re)creates/updates
19:03:58,678 DEBUG AbstractFlushingEventListener:79 - Flushed: 0 insertions, 0 updates, 0 deletions to 2 objects