Skip to content

Commit

Permalink
HHH-11076 - Lazy collections ignore filters when allowLoadOutsideTran…
Browse files Browse the repository at this point in the history
…saction is true
  • Loading branch information
Giovanni Lovato authored and vladmihalcea committed Sep 19, 2016
1 parent 87e69c9 commit ae40de1
Show file tree
Hide file tree
Showing 3 changed files with 127 additions and 3 deletions.
Expand Up @@ -10,13 +10,15 @@
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;

import org.hibernate.AssertionFailure;
import org.hibernate.Filter;
import org.hibernate.FlushMode;
import org.hibernate.HibernateException;
import org.hibernate.LazyInitializationException;
Expand Down Expand Up @@ -73,6 +75,7 @@ public abstract class AbstractPersistentCollection implements Serializable, Pers

private String sessionFactoryUuid;
private boolean allowLoadOutsideTransaction;
private Map<String, Filter> enabledFilters;

/**
* Not called by Hibernate, but used by non-JDK serialization,
Expand All @@ -83,6 +86,7 @@ public AbstractPersistentCollection() {

protected AbstractPersistentCollection(SharedSessionContractImplementor session) {
this.session = session;
enabledFilters = new HashMap<>( session.getLoadQueryInfluencers().getEnabledFilters() );
}

@Override
Expand Down Expand Up @@ -218,7 +222,6 @@ else if ( !session.isConnected() ) {
}
}


SharedSessionContractImplementor originalSession = null;
boolean isJTA = false;

Expand All @@ -227,9 +230,8 @@ else if ( !session.isConnected() ) {
originalSession = session;
session = tempSession;


isJTA = session.getTransactionCoordinator().getTransactionCoordinatorBuilder().isJta();

if ( !isJTA ) {
// Explicitly handle the transactions only if we're not in
// a JTA environment. A lazy loading temporary session can
Expand Down Expand Up @@ -277,6 +279,7 @@ private SharedSessionContractImplementor openTemporarySessionForLoading() {
final SharedSessionContractImplementor session = (SharedSessionContractImplementor) sf.openSession();
session.getPersistenceContext().setDefaultReadOnly( true );
session.setFlushMode( FlushMode.MANUAL );
session.getLoadQueryInfluencers().getEnabledFilters().putAll( enabledFilters );
return session;
}

Expand Down
@@ -0,0 +1,47 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.jpa.test.hibernateFilters;

import java.util.ArrayList;
import java.util.List;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;

import org.hibernate.annotations.Filter;

/**
* @author Vlad Mihalcea
*/
@Entity
public class AccountGroup {

@Id
private Long id;

@OneToMany
@JoinColumn(name = "group_id")
@Filter( name = "byRegion", condition = "region_cd = :region" )
private List<Account> accounts = new ArrayList<>();

public Long getId() {
return id;
}

public void setId(Long id) {
this.id = id;
}

public List<Account> getAccounts() {
return accounts;
}

public void setAccounts(List<Account> accounts) {
this.accounts = accounts;
}
}
@@ -0,0 +1,74 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.jpa.test.hibernateFilters;

import java.util.Map;

import org.hibernate.Session;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;

import org.junit.Test;

import static org.hibernate.testing.transaction.TransactionUtil.doInJPA;
import static org.junit.Assert.assertEquals;

/**
* @author Vlad Mihalcea
*/
public class ProxyPreservingFiltersOutsideInitialSessionTest
extends BaseEntityManagerFunctionalTestCase {
@Override
public Class[] getAnnotatedClasses() {
return new Class[] {
AccountGroup.class,
Account.class
};
}

@Override
protected Map buildSettings() {
Map settings = super.buildSettings();
settings.put( AvailableSettings.ENABLE_LAZY_LOAD_NO_TRANS, "true" );
return settings;
}

@Test
public void testPreserveFilters() {

doInJPA( this::entityManagerFactory, entityManager -> {
AccountGroup accountGroup = new AccountGroup();
accountGroup.setId( 1L );
entityManager.persist( accountGroup );

Account account = new Account();
account.setName( "A1" );
account.setRegionCode( "Europe" );
entityManager.persist( account );
accountGroup.getAccounts().add( account );

account = new Account();
account.setName( "A2" );
account.setRegionCode( "Europe" );
entityManager.persist( account );
accountGroup.getAccounts().add( account );

account = new Account();
account.setName( "A3" );
account.setRegionCode( "US" );
entityManager.persist( account );
accountGroup.getAccounts().add( account );
} );

AccountGroup group = doInJPA( this::entityManagerFactory, entityManager -> {
entityManager.unwrap( Session.class ).enableFilter( "byRegion" ).setParameter( "region", "US" );
return entityManager.find( AccountGroup.class, 1L );
} );

assertEquals(1, group.getAccounts().size());
}
}

0 comments on commit ae40de1

Please sign in to comment.