Search in sources :

Example 36 with CollectionEntry

use of org.hibernate.engine.spi.CollectionEntry in project hibernate-orm by hibernate.

the class UnversionedCascadeDereferencedCollectionTest method testGetAndNullifyCollection.

@Test
@TestForIssue(jiraKey = "HHH-9777")
public void testGetAndNullifyCollection() {
    Session s = openSession();
    s.getTransaction().begin();
    UnversionedCascadeOne one = new UnversionedCascadeOne();
    assertNull(one.getManies());
    s.save(one);
    assertNull(one.getManies());
    EntityEntry eeOne = getEntityEntry(s, one);
    assertNull(eeOne.getLoadedValue("manies"));
    s.flush();
    assertNull(one.getManies());
    assertNull(eeOne.getLoadedValue("manies"));
    s.getTransaction().commit();
    s.close();
    final String role = UnversionedCascadeOne.class.getName() + ".manies";
    s = openSession();
    s.getTransaction().begin();
    one = (UnversionedCascadeOne) s.get(UnversionedCascadeOne.class, one.getId());
    // When returned by Session.get(), one.getManies() will return a PersistentCollection;
    // the EntityEntry loaded state should contain the same PersistentCollection.
    eeOne = getEntityEntry(s, one);
    assertNotNull(one.getManies());
    AbstractPersistentCollection maniesEEOneStateOrig = (AbstractPersistentCollection) eeOne.getLoadedValue("manies");
    assertSame(one.getManies(), maniesEEOneStateOrig);
    // Ensure maniesEEOneStateOrig has role, key, and session properly defined (even though one.manies == null)
    assertEquals(role, maniesEEOneStateOrig.getRole());
    assertEquals(one.getId(), maniesEEOneStateOrig.getKey());
    assertSame(s, maniesEEOneStateOrig.getSession());
    // Ensure there is a CollectionEntry for maniesEEOneStateOrig and that the role, persister, and key are set properly.
    CollectionEntry ceManies = getCollectionEntry(s, maniesEEOneStateOrig);
    assertNotNull(ceManies);
    assertEquals(role, ceManies.getRole());
    assertSame(sessionFactory().getCollectionPersister(role), ceManies.getLoadedPersister());
    assertEquals(one.getId(), ceManies.getKey());
    // nullify collection
    one.setManies(null);
    s.flush();
    // Ensure the same EntityEntry is being used.
    assertSame(eeOne, getEntityEntry(s, one));
    // Ensure one.getManies() is still null.
    assertNull(one.getManies());
    // Ensure CollectionEntry for maniesEEOneStateOrig is no longer in the PersistenceContext.
    assertNull(getCollectionEntry(s, maniesEEOneStateOrig));
    // Ensure the original CollectionEntry has role, persister, and key set to null.
    assertNull(ceManies.getRole());
    assertNull(ceManies.getLoadedPersister());
    assertNull(ceManies.getKey());
    // Ensure the PersistentCollection (that was previously returned by eeOne.getLoadedState())
    // has key and role set to null.
    assertNull(maniesEEOneStateOrig.getKey());
    assertNull(maniesEEOneStateOrig.getRole());
    // Ensure eeOne.getLoadedState() returns null for collection afterQuery flush.
    assertNull(eeOne.getLoadedValue("manies"));
    // Ensure the session in maniesEEOneStateOrig has been unset.
    assertNull(maniesEEOneStateOrig.getSession());
    s.getTransaction().commit();
    s.close();
}
Also used : EntityEntry(org.hibernate.engine.spi.EntityEntry) AbstractPersistentCollection(org.hibernate.collection.internal.AbstractPersistentCollection) CollectionEntry(org.hibernate.engine.spi.CollectionEntry) Session(org.hibernate.Session) Test(org.junit.Test) TestForIssue(org.hibernate.testing.TestForIssue)

Example 37 with CollectionEntry

use of org.hibernate.engine.spi.CollectionEntry in project hibernate-orm by hibernate.

the class MultipleSessionCollectionWarningTest method testUnsetSessionCannotOverwriteConnectedSesssionFlushed.

@Test
@TestForIssue(jiraKey = "HHH-9518")
public void testUnsetSessionCannotOverwriteConnectedSesssionFlushed() {
    Parent p = new Parent();
    Child c = new Child();
    p.children.add(c);
    Session s1 = openSession();
    s1.getTransaction().begin();
    s1.saveOrUpdate(p);
    // flush the session so that p.children will contain its role
    s1.flush();
    // The collection is "connected" to s1 because it contains the CollectionEntry
    CollectionEntry ce = ((SessionImplementor) s1).getPersistenceContext().getCollectionEntry((PersistentCollection) p.children);
    assertNotNull(ce);
    // the collection session should be s1
    assertSame(s1, ((AbstractPersistentCollection) p.children).getSession());
    Session s2 = openSession();
    s2.getTransaction().begin();
    Triggerable triggerable = logInspection.watchForLogMessages("HHH000471:");
    assertFalse(triggerable.wasTriggered());
    // The following should trigger warning because we're unsetting a different session
    // We should not do this in practice; it is done here only to force the warning.
    // The collection role and key should be included in the message (no way to test that other than inspection).
    assertFalse(((PersistentCollection) p.children).unsetSession((SessionImplementor) s2));
    assertTrue(triggerable.wasTriggered());
    // collection's session should still be s1
    assertSame(s1, ((AbstractPersistentCollection) p.children).getSession());
    s2.getTransaction().rollback();
    s2.close();
    s1.getTransaction().rollback();
    s1.close();
}
Also used : CollectionEntry(org.hibernate.engine.spi.CollectionEntry) SessionImplementor(org.hibernate.engine.spi.SessionImplementor) Triggerable(org.hibernate.testing.logger.Triggerable) Session(org.hibernate.Session) Test(org.junit.Test) TestForIssue(org.hibernate.testing.TestForIssue)

Example 38 with CollectionEntry

use of org.hibernate.engine.spi.CollectionEntry in project hibernate-orm by hibernate.

the class MultipleSessionCollectionWarningTest method testUnsetSessionCannotOverwriteNonConnectedSesssion.

@Test
@TestForIssue(jiraKey = "HHH-9518")
public void testUnsetSessionCannotOverwriteNonConnectedSesssion() {
    Parent p = new Parent();
    Child c = new Child();
    p.children.add(c);
    Session s1 = openSession();
    s1.getTransaction().begin();
    s1.saveOrUpdate(p);
    // Now remove the collection from the PersistenceContext without unsetting its session
    // This should never be done in practice; it is done here only to test that the warning
    // gets logged. s1 will not function properly so the transaction will ultimately need
    // to be rolled-back.
    CollectionEntry ce = (CollectionEntry) ((SessionImplementor) s1).getPersistenceContext().getCollectionEntries().remove(p.children);
    assertNotNull(ce);
    // the collection session should still be s1; the collection is no longer "connected" because its
    // CollectionEntry has been removed.
    assertSame(s1, ((AbstractPersistentCollection) p.children).getSession());
    Session s2 = openSession();
    s2.getTransaction().begin();
    Triggerable triggerable = logInspection.watchForLogMessages("HHH000471:");
    assertFalse(triggerable.wasTriggered());
    // The following should trigger warning because we're unsetting a different session.
    // We should not do this in practice; it is done here only to force the warning.
    // Since s1 was not flushed, the collection role will not be known (no way to test that).
    assertFalse(((PersistentCollection) p.children).unsetSession((SessionImplementor) s2));
    assertTrue(triggerable.wasTriggered());
    // collection's session should still be s1
    assertSame(s1, ((AbstractPersistentCollection) p.children).getSession());
    s2.getTransaction().rollback();
    s2.close();
    s1.getTransaction().rollback();
    s1.close();
}
Also used : CollectionEntry(org.hibernate.engine.spi.CollectionEntry) SessionImplementor(org.hibernate.engine.spi.SessionImplementor) Triggerable(org.hibernate.testing.logger.Triggerable) Session(org.hibernate.Session) Test(org.junit.Test) TestForIssue(org.hibernate.testing.TestForIssue)

Example 39 with CollectionEntry

use of org.hibernate.engine.spi.CollectionEntry in project hibernate-orm by hibernate.

the class AbstractFlushingEventListener method postFlush.

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Post-flushing section
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/**
	 * 1. Recreate the collection key -> collection map
	 * 2. rebuild the collection entries
	 * 3. call Interceptor.postFlush()
	 */
protected void postFlush(SessionImplementor session) throws HibernateException {
    LOG.trace("Post flush");
    final PersistenceContext persistenceContext = session.getPersistenceContext();
    persistenceContext.getCollectionsByKey().clear();
    // the database has changed now, so the subselect results need to be invalidated
    // the batch fetching queues should also be cleared - especially the collection batch fetching one
    persistenceContext.getBatchFetchQueue().clear();
    for (Map.Entry<PersistentCollection, CollectionEntry> me : IdentityMap.concurrentEntries(persistenceContext.getCollectionEntries())) {
        CollectionEntry collectionEntry = me.getValue();
        PersistentCollection persistentCollection = me.getKey();
        collectionEntry.postFlush(persistentCollection);
        if (collectionEntry.getLoadedPersister() == null) {
            //if the collection is dereferenced, unset its session reference and remove from the session cache
            //iter.remove(); //does not work, since the entrySet is not backed by the set
            persistentCollection.unsetSession(session);
            persistenceContext.getCollectionEntries().remove(persistentCollection);
        } else {
            //otherwise recreate the mapping between the collection and its key
            CollectionKey collectionKey = new CollectionKey(collectionEntry.getLoadedPersister(), collectionEntry.getLoadedKey());
            persistenceContext.getCollectionsByKey().put(collectionKey, persistentCollection);
        }
    }
}
Also used : PersistentCollection(org.hibernate.collection.spi.PersistentCollection) CollectionEntry(org.hibernate.engine.spi.CollectionEntry) PersistenceContext(org.hibernate.engine.spi.PersistenceContext) CollectionKey(org.hibernate.engine.spi.CollectionKey) Map(java.util.Map) IdentityMap(org.hibernate.internal.util.collections.IdentityMap)

Example 40 with CollectionEntry

use of org.hibernate.engine.spi.CollectionEntry in project hibernate-orm by hibernate.

the class CollectionLoadContext method endLoadingCollection.

private void endLoadingCollection(LoadingCollectionEntry lce, CollectionPersister persister) {
    LOG.tracev("Ending loading collection [{0}]", lce);
    final SharedSessionContractImplementor session = getLoadContext().getPersistenceContext().getSession();
    // warning: can cause a recursive calls! (proxy initialization)
    final boolean hasNoQueuedAdds = lce.getCollection().endRead();
    if (persister.getCollectionType().hasHolder()) {
        getLoadContext().getPersistenceContext().addCollectionHolder(lce.getCollection());
    }
    CollectionEntry ce = getLoadContext().getPersistenceContext().getCollectionEntry(lce.getCollection());
    if (ce == null) {
        ce = getLoadContext().getPersistenceContext().addInitializedCollection(persister, lce.getCollection(), lce.getKey());
    } else {
        ce.postInitialize(lce.getCollection());
    //			if (ce.getLoadedPersister().getBatchSize() > 1) { // not the best place for doing this, moved into ce.postInitialize
    //				getLoadContext().getPersistenceContext().getBatchFetchQueue().removeBatchLoadableCollection(ce); 
    //			}
    }
    // add to cache if:
    boolean addToCache = // there were no queued additions
    hasNoQueuedAdds && // and the role has a cache
    persister.hasCache() && // and this is not a forced initialization during flush
    session.getCacheMode().isPutEnabled() && !ce.isDoremove();
    if (addToCache) {
        addCollectionToCache(lce, persister);
    }
    if (LOG.isDebugEnabled()) {
        LOG.debugf("Collection fully initialized: %s", MessageHelper.collectionInfoString(persister, lce.getCollection(), lce.getKey(), session));
    }
    if (session.getFactory().getStatistics().isStatisticsEnabled()) {
        session.getFactory().getStatistics().loadCollection(persister.getRole());
    }
}
Also used : CollectionEntry(org.hibernate.engine.spi.CollectionEntry) SharedSessionContractImplementor(org.hibernate.engine.spi.SharedSessionContractImplementor)

Aggregations

CollectionEntry (org.hibernate.engine.spi.CollectionEntry)42 Session (org.hibernate.Session)19 TestForIssue (org.hibernate.testing.TestForIssue)19 Test (org.junit.Test)19 EntityEntry (org.hibernate.engine.spi.EntityEntry)16 AbstractPersistentCollection (org.hibernate.collection.internal.AbstractPersistentCollection)12 PersistentCollection (org.hibernate.collection.spi.PersistentCollection)11 Serializable (java.io.Serializable)6 SessionImplementor (org.hibernate.engine.spi.SessionImplementor)6 Map (java.util.Map)5 Triggerable (org.hibernate.testing.logger.Triggerable)5 HibernateException (org.hibernate.HibernateException)4 IdentityMap (org.hibernate.internal.util.collections.IdentityMap)4 CollectionPersister (org.hibernate.persister.collection.CollectionPersister)4 HashMap (java.util.HashMap)3 EntityKey (org.hibernate.engine.spi.EntityKey)3 PersistenceContext (org.hibernate.engine.spi.PersistenceContext)3 IdentityHashMap (java.util.IdentityHashMap)2 ConcurrentMap (java.util.concurrent.ConcurrentMap)2 CollectionKey (org.hibernate.engine.spi.CollectionKey)2