mirror of
https://github.com/hibernate/hibernate-orm
synced 2025-02-22 02:58:05 +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) {
|
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);
|
Set[] keySets = transpose(keys);
|
||||||
|
|
||||||
@ -1017,6 +1023,17 @@ private void createSubselects(List keys, QueryParameters queryParameters, Sessio
|
|||||||
queryParameters
|
queryParameters
|
||||||
);
|
);
|
||||||
final Iterator iter = keys.iterator();
|
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() ) {
|
while ( iter.hasNext() ) {
|
||||||
|
|
||||||
final EntityKey[] rowKeys = (EntityKey[]) iter.next();
|
final EntityKey[] rowKeys = (EntityKey[]) iter.next();
|
||||||
@ -1033,6 +1050,15 @@ private void createSubselects(List keys, QueryParameters queryParameters, Sessio
|
|||||||
namedParameterLocMap
|
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()
|
session.getPersistenceContext()
|
||||||
.getBatchFetchQueue()
|
.getBatchFetchQueue()
|
||||||
.addSubselect( rowKeys[i], subselectFetch );
|
.addSubselect( rowKeys[i], subselectFetch );
|
||||||
|
@ -27,8 +27,11 @@
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import javax.persistence.CascadeType;
|
import javax.persistence.CascadeType;
|
||||||
import javax.persistence.Entity;
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.FetchType;
|
||||||
import javax.persistence.GeneratedValue;
|
import javax.persistence.GeneratedValue;
|
||||||
import javax.persistence.Id;
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.JoinTable;
|
||||||
|
import javax.persistence.ManyToOne;
|
||||||
import javax.persistence.OneToMany;
|
import javax.persistence.OneToMany;
|
||||||
import javax.persistence.Table;
|
import javax.persistence.Table;
|
||||||
|
|
||||||
@ -42,6 +45,7 @@
|
|||||||
import org.hibernate.annotations.FetchMode;
|
import org.hibernate.annotations.FetchMode;
|
||||||
import org.hibernate.cfg.Configuration;
|
import org.hibernate.cfg.Configuration;
|
||||||
import org.hibernate.cfg.Environment;
|
import org.hibernate.cfg.Environment;
|
||||||
|
import org.hibernate.testing.TestForIssue;
|
||||||
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
|
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
@ -60,6 +64,7 @@ public void configure(Configuration cfg) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@TestForIssue( jiraKey = "HHH-10679")
|
||||||
public void testSubselectFetchFromEntityBatch() {
|
public void testSubselectFetchFromEntityBatch() {
|
||||||
Session s = openSession();
|
Session s = openSession();
|
||||||
Transaction t = s.beginTransaction();
|
Transaction t = s.beginTransaction();
|
||||||
@ -195,6 +200,136 @@ public void testSubselectFetchFromQueryList() {
|
|||||||
s.close();
|
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() {
|
public Class<?>[] getAnnotatedClasses() {
|
||||||
return new Class<?>[] { EmployeeGroup.class, Employee.class };
|
return new Class<?>[] { EmployeeGroup.class, Employee.class };
|
||||||
}
|
}
|
||||||
@ -208,8 +343,15 @@ private static class EmployeeGroup {
|
|||||||
@GeneratedValue
|
@GeneratedValue
|
||||||
private Long id;
|
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)
|
@OneToMany(cascade = CascadeType.ALL)
|
||||||
@Fetch(FetchMode.SUBSELECT)
|
@Fetch(FetchMode.SUBSELECT)
|
||||||
|
@JoinTable(name="EmployeeGroup_employees")
|
||||||
private List<Employee> employees = new ArrayList<Employee>();
|
private List<Employee> employees = new ArrayList<Employee>();
|
||||||
|
|
||||||
public EmployeeGroup(long id) {
|
public EmployeeGroup(long id) {
|
||||||
@ -220,6 +362,22 @@ public EmployeeGroup(long id) {
|
|||||||
protected EmployeeGroup() {
|
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) {
|
public boolean addEmployee(Employee employee) {
|
||||||
return employees.add(employee);
|
return employees.add(employee);
|
||||||
}
|
}
|
||||||
@ -247,6 +405,10 @@ private static class Employee {
|
|||||||
private Long id;
|
private Long id;
|
||||||
private String name;
|
private String name;
|
||||||
|
|
||||||
|
@OneToMany(cascade = CascadeType.ALL)
|
||||||
|
@Fetch(FetchMode.SUBSELECT)
|
||||||
|
private List<Employee> collaborators = new ArrayList<Employee>();
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
@ -259,6 +421,14 @@ public Employee(String name) {
|
|||||||
this.name = name;
|
this.name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean addCollaborator(Employee employee) {
|
||||||
|
return collaborators.add(employee);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Employee> getCollaborators() {
|
||||||
|
return collaborators;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return name;
|
return name;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user