mirror of
https://github.com/hibernate/hibernate-orm
synced 2025-02-21 10:34:51 +00:00
HHH-10679 : Add TRACE logging and another test
This commit is contained in:
parent
229d2e945b
commit
ca159c5a6b
@ -1005,7 +1005,13 @@ private static Set[] transpose( List keys ) {
|
||||
}
|
||||
|
||||
private void createSubselects(List keys, QueryParameters queryParameters, SessionImplementor session) {
|
||||
if ( keys.size() > 1 ) { //if we only returned one entity, query by key is more efficient
|
||||
if ( keys.size() < 2 ) {
|
||||
LOG.tracef(
|
||||
"Loader [%s] Skipping subselect because there are fewer than 2 results, so query by key is more efficient.",
|
||||
getClass().getName()
|
||||
);
|
||||
}
|
||||
else {
|
||||
|
||||
Set[] keySets = transpose(keys);
|
||||
|
||||
@ -1017,6 +1023,17 @@ private void createSubselects(List keys, QueryParameters queryParameters, Sessio
|
||||
queryParameters
|
||||
);
|
||||
final Iterator iter = keys.iterator();
|
||||
|
||||
if ( LOG.isTraceEnabled() && loadables.length > 1 ) {
|
||||
LOG.tracef(
|
||||
"Loader [%s] : persisters [%s], aliases [%s], query [%s]",
|
||||
getClass().getName(),
|
||||
Arrays.asList( loadables ),
|
||||
Arrays.asList( aliases ),
|
||||
subselectQueryString
|
||||
);
|
||||
}
|
||||
|
||||
while ( iter.hasNext() ) {
|
||||
|
||||
final EntityKey[] rowKeys = (EntityKey[]) iter.next();
|
||||
@ -1033,6 +1050,15 @@ private void createSubselects(List keys, QueryParameters queryParameters, Sessio
|
||||
namedParameterLocMap
|
||||
);
|
||||
|
||||
LOG.tracef(
|
||||
"Loader [%s] created subselect: persister [%s], alias [%s], query [%s], entityKeys [%s]",
|
||||
getClass().getName(),
|
||||
loadables[i],
|
||||
aliases[i],
|
||||
subselectQueryString,
|
||||
keySets[i]
|
||||
);
|
||||
|
||||
session.getPersistenceContext()
|
||||
.getBatchFetchQueue()
|
||||
.addSubselect( rowKeys[i], subselectFetch );
|
||||
|
@ -27,8 +27,11 @@
|
||||
import java.util.List;
|
||||
import javax.persistence.CascadeType;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.FetchType;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.JoinTable;
|
||||
import javax.persistence.ManyToOne;
|
||||
import javax.persistence.OneToMany;
|
||||
import javax.persistence.Table;
|
||||
|
||||
@ -42,6 +45,7 @@
|
||||
import org.hibernate.annotations.FetchMode;
|
||||
import org.hibernate.cfg.Configuration;
|
||||
import org.hibernate.cfg.Environment;
|
||||
import org.hibernate.testing.TestForIssue;
|
||||
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
@ -60,6 +64,7 @@ public void configure(Configuration cfg) {
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestForIssue( jiraKey = "HHH-10679")
|
||||
public void testSubselectFetchFromEntityBatch() {
|
||||
Session s = openSession();
|
||||
Transaction t = s.beginTransaction();
|
||||
@ -195,6 +200,136 @@ public void testSubselectFetchFromQueryList() {
|
||||
s.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestForIssue( jiraKey = "HHH-10679")
|
||||
public void testMultiSubselectFetchSamePersisterQueryList() {
|
||||
Session s = openSession();
|
||||
Transaction t = s.beginTransaction();
|
||||
EmployeeGroup group1 = new EmployeeGroup();
|
||||
Employee employee1 = new Employee("Jane");
|
||||
Employee employee2 = new Employee("Jeff");
|
||||
group1.addEmployee( employee1 );
|
||||
group1.addEmployee( employee2 );
|
||||
group1.setManager( new Employee( "group1 manager" ) );
|
||||
group1.getManager().addCollaborator( new Employee( "group1 manager's collaborator#1" ) );
|
||||
group1.getManager().addCollaborator( new Employee( "group1 manager's collaborator#2" ) );
|
||||
group1.setLead( new Employee( "group1 lead" ) );
|
||||
group1.getLead().addCollaborator( new Employee( "group1 lead's collaborator#1" ) );
|
||||
EmployeeGroup group2 = new EmployeeGroup();
|
||||
Employee employee3 = new Employee("Joan");
|
||||
Employee employee4 = new Employee("John");
|
||||
group2.addEmployee( employee3 );
|
||||
group2.addEmployee( employee4 );
|
||||
group2.setManager( new Employee( "group2 manager" ) );
|
||||
group2.getManager().addCollaborator( new Employee( "group2 manager's collaborator#1" ) );
|
||||
group2.getManager().addCollaborator( new Employee( "group2 manager's collaborator#2" ) );
|
||||
group2.getManager().addCollaborator( new Employee( "group2 manager's collaborator#3" ) );
|
||||
group2.setLead( new Employee( "group2 lead" ) );
|
||||
group2.getLead().addCollaborator( new Employee( "group2 lead's collaborator#1" ) );
|
||||
group2.getLead().addCollaborator( new Employee( "group2 lead's collaborator#2" ) );
|
||||
s.save( group1 );
|
||||
s.save( group2 );
|
||||
s.flush();
|
||||
|
||||
s.clear();
|
||||
|
||||
sessionFactory().getStatistics().clear();
|
||||
|
||||
EmployeeGroup[] groups = new EmployeeGroup[] {
|
||||
(EmployeeGroup) s.load(EmployeeGroup.class, group1.getId()),
|
||||
(EmployeeGroup) s.load(EmployeeGroup.class, group2.getId())
|
||||
};
|
||||
|
||||
// groups should only contain proxies
|
||||
assertEquals( 0, sessionFactory().getStatistics().getPrepareStatementCount() );
|
||||
|
||||
for (EmployeeGroup group : groups) {
|
||||
assertFalse( Hibernate.isInitialized( group ) );
|
||||
}
|
||||
|
||||
assertEquals( 0, sessionFactory().getStatistics().getPrepareStatementCount() );
|
||||
|
||||
|
||||
for (int i = 0 ; i < groups.length; i++ ) {
|
||||
// Both groups get initialized and are added to the PersistenceContext when i == 0;
|
||||
// Still need to call Hibernate.initialize( groups[i] ) for i > 0 so that the entity
|
||||
// in the PersistenceContext gets assigned to its respective proxy target (is this a
|
||||
// bug???)
|
||||
Hibernate.initialize( groups[ i ] );
|
||||
assertTrue( Hibernate.isInitialized( groups[i] ) );
|
||||
assertTrue( Hibernate.isInitialized( groups[i].getLead() ) );
|
||||
assertFalse( Hibernate.isInitialized( groups[i].getLead().getCollaborators() ) );
|
||||
assertTrue( Hibernate.isInitialized( groups[i].getManager() ) );
|
||||
assertFalse( Hibernate.isInitialized( groups[i].getManager().getCollaborators() ) );
|
||||
// the collections should be uninitialized
|
||||
assertFalse( Hibernate.isInitialized( groups[i].getEmployees() ) );
|
||||
}
|
||||
|
||||
// both Group proxies should have been loaded in the same batch;
|
||||
assertEquals( 1, sessionFactory().getStatistics().getPrepareStatementCount() );
|
||||
sessionFactory().getStatistics().clear();
|
||||
|
||||
for (EmployeeGroup group : groups) {
|
||||
assertTrue( Hibernate.isInitialized( group ) );
|
||||
assertFalse( Hibernate.isInitialized( group.getEmployees() ) );
|
||||
}
|
||||
|
||||
assertEquals( 0, sessionFactory().getStatistics().getPrepareStatementCount() );
|
||||
|
||||
// now initialize the collection in the first; collections in both groups
|
||||
// should get initialized
|
||||
Hibernate.initialize( groups[0].getEmployees() );
|
||||
|
||||
assertEquals( 1, sessionFactory().getStatistics().getPrepareStatementCount() );
|
||||
sessionFactory().getStatistics().clear();
|
||||
|
||||
// all EmployeeGroup#employees should be initialized now
|
||||
for (EmployeeGroup group : groups) {
|
||||
assertTrue( Hibernate.isInitialized( group.getEmployees() ) );
|
||||
assertFalse( Hibernate.isInitialized( group.getLead().getCollaborators() ) );
|
||||
assertFalse( Hibernate.isInitialized( group.getManager().getCollaborators() ) );
|
||||
}
|
||||
|
||||
assertEquals( 0, sessionFactory().getStatistics().getPrepareStatementCount() );
|
||||
|
||||
// now initialize groups[0].getLead().getCollaborators();
|
||||
// groups[1].getLead().getCollaborators() should also be initialized
|
||||
Hibernate.initialize( groups[0].getLead().getCollaborators() );
|
||||
|
||||
assertEquals( 1, sessionFactory().getStatistics().getPrepareStatementCount() );
|
||||
sessionFactory().getStatistics().clear();
|
||||
|
||||
for (EmployeeGroup group : groups) {
|
||||
assertTrue( Hibernate.isInitialized( group.getLead().getCollaborators() ) );
|
||||
assertFalse( Hibernate.isInitialized( group.getManager().getCollaborators() ) );
|
||||
}
|
||||
|
||||
assertEquals( 0, sessionFactory().getStatistics().getPrepareStatementCount() );
|
||||
|
||||
// now initialize groups[0].getManager().getCollaborators();
|
||||
// groups[1].getManager().getCollaborators() should also be initialized
|
||||
Hibernate.initialize( groups[0].getManager().getCollaborators() );
|
||||
|
||||
assertEquals( 1, sessionFactory().getStatistics().getPrepareStatementCount() );
|
||||
sessionFactory().getStatistics().clear();
|
||||
|
||||
for (EmployeeGroup group : groups) {
|
||||
assertTrue( Hibernate.isInitialized( group.getManager().getCollaborators() ) );
|
||||
}
|
||||
|
||||
assertEquals( 0, sessionFactory().getStatistics().getPrepareStatementCount() );
|
||||
|
||||
assertEquals( group1.getLead().getCollaborators().size(), groups[0].getLead().getCollaborators().size() );
|
||||
assertEquals( group2.getLead().getCollaborators().size(), groups[1].getLead().getCollaborators().size() );
|
||||
assertEquals( group1.getManager().getCollaborators().size(), groups[0].getManager().getCollaborators().size() );
|
||||
assertEquals( group2.getManager().getCollaborators().size(), groups[1].getManager().getCollaborators().size() );
|
||||
|
||||
assertEquals( 0, sessionFactory().getStatistics().getPrepareStatementCount() );
|
||||
|
||||
t.rollback();
|
||||
s.close();
|
||||
}
|
||||
|
||||
public Class<?>[] getAnnotatedClasses() {
|
||||
return new Class<?>[] { EmployeeGroup.class, Employee.class };
|
||||
}
|
||||
@ -208,8 +343,15 @@ private static class EmployeeGroup {
|
||||
@GeneratedValue
|
||||
private Long id;
|
||||
|
||||
@ManyToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
|
||||
private Employee manager;
|
||||
|
||||
@ManyToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
|
||||
private Employee lead;
|
||||
|
||||
@OneToMany(cascade = CascadeType.ALL)
|
||||
@Fetch(FetchMode.SUBSELECT)
|
||||
@JoinTable(name="EmployeeGroup_employees")
|
||||
private List<Employee> employees = new ArrayList<Employee>();
|
||||
|
||||
public EmployeeGroup(long id) {
|
||||
@ -220,6 +362,22 @@ public EmployeeGroup(long id) {
|
||||
protected EmployeeGroup() {
|
||||
}
|
||||
|
||||
public Employee getManager() {
|
||||
return manager;
|
||||
}
|
||||
|
||||
public void setManager(Employee manager) {
|
||||
this.manager = manager;
|
||||
}
|
||||
|
||||
public Employee getLead() {
|
||||
return lead;
|
||||
}
|
||||
|
||||
public void setLead(Employee lead) {
|
||||
this.lead = lead;
|
||||
}
|
||||
|
||||
public boolean addEmployee(Employee employee) {
|
||||
return employees.add(employee);
|
||||
}
|
||||
@ -247,6 +405,10 @@ private static class Employee {
|
||||
private Long id;
|
||||
private String name;
|
||||
|
||||
@OneToMany(cascade = CascadeType.ALL)
|
||||
@Fetch(FetchMode.SUBSELECT)
|
||||
private List<Employee> collaborators = new ArrayList<Employee>();
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
@ -259,6 +421,14 @@ public Employee(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public boolean addCollaborator(Employee employee) {
|
||||
return collaborators.add(employee);
|
||||
}
|
||||
|
||||
public List<Employee> getCollaborators() {
|
||||
return collaborators;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name;
|
||||
|
Loading…
x
Reference in New Issue
Block a user