HHH-9305 : HQL FromElement is not reused in some cases resulting in an additional join
(cherry picked from commit a0663f0d6c
)
This commit is contained in:
parent
8b5f959200
commit
88a93f8c03
|
@ -454,10 +454,8 @@ public class DotNode extends FromReferenceNode implements DisplayableNode, Selec
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
boolean found = elem != null;
|
boolean found = elem != null;
|
||||||
// even though we might find a pre-existing element by join path, for FromElements originating in a from-clause
|
// even though we might find a pre-existing element by join path, we may not be able to reuse it...
|
||||||
// we should only ever use the found element if the aliases match (null != null here). Implied joins are
|
boolean useFoundFromElement = found && canReuse( elem, classAlias );
|
||||||
// always (?) ok to reuse.
|
|
||||||
boolean useFoundFromElement = found && ( elem.isImplied() || areSame( classAlias, elem.getClassAlias() ) );
|
|
||||||
|
|
||||||
if ( ! useFoundFromElement ) {
|
if ( ! useFoundFromElement ) {
|
||||||
// If this is an implied join in a from element, then use the impled join type which is part of the
|
// If this is an implied join in a from element, then use the impled join type which is part of the
|
||||||
|
@ -502,9 +500,23 @@ public class DotNode extends FromReferenceNode implements DisplayableNode, Selec
|
||||||
setFromElement( elem ); // This 'dot' expression now refers to the resulting from element.
|
setFromElement( elem ); // This 'dot' expression now refers to the resulting from element.
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean areSame(String alias1, String alias2) {
|
private boolean canReuse(FromElement fromElement, String requestedAlias) {
|
||||||
// again, null != null here
|
// implicit joins are always(?) ok to reuse
|
||||||
return !StringHelper.isEmpty( alias1 ) && !StringHelper.isEmpty( alias2 ) && alias1.equals( alias2 );
|
if ( isImplicitJoin( fromElement ) ) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if the from-clauses are the same, we can be a little more aggressive in terms of what we reuse
|
||||||
|
if ( fromElement.getFromClause() == getWalker().getCurrentFromClause() ) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// otherwise (subquery case) dont reuse the fromElement if we are processing the from-clause of the subquery
|
||||||
|
return getWalker().getCurrentClauseType() != SqlTokenTypes.FROM;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isImplicitJoin(FromElement fromElement) {
|
||||||
|
return fromElement.isImplied();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setImpliedJoin(FromElement elem) {
|
private void setImpliedJoin(FromElement elem) {
|
||||||
|
|
|
@ -137,6 +137,14 @@ public class ASTParserLoadingTest extends BaseCoreFunctionalTestCase {
|
||||||
"legacy/Marelo.hbm.xml"
|
"legacy/Marelo.hbm.xml"
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@Override
|
||||||
|
protected Class<?>[] getAnnotatedClasses() {
|
||||||
|
return new Class[] {
|
||||||
|
Department.class,
|
||||||
|
Employee.class,
|
||||||
|
Title.class
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void configure(Configuration cfg) {
|
public void configure(Configuration cfg) {
|
||||||
|
@ -1010,6 +1018,145 @@ public class ASTParserLoadingTest extends BaseCoreFunctionalTestCase {
|
||||||
s.close();
|
s.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestForIssue( jiraKey = "HHH-9305")
|
||||||
|
public void testExplicitToOneInnerJoin() {
|
||||||
|
final Employee employee1 = new Employee();
|
||||||
|
employee1.setFirstName( "Jane" );
|
||||||
|
employee1.setLastName( "Doe" );
|
||||||
|
final Title title1 = new Title();
|
||||||
|
title1.setDescription( "Jane's description" );
|
||||||
|
final Department dept1 = new Department();
|
||||||
|
dept1.setDeptName( "Jane's department" );
|
||||||
|
employee1.setTitle( title1 );
|
||||||
|
employee1.setDepartment( dept1 );
|
||||||
|
|
||||||
|
final Employee employee2 = new Employee();
|
||||||
|
employee2.setFirstName( "John" );
|
||||||
|
employee2.setLastName( "Doe" );
|
||||||
|
final Title title2 = new Title();
|
||||||
|
title2.setDescription( "John's title" );
|
||||||
|
employee2.setTitle( title2 );
|
||||||
|
|
||||||
|
Session s = openSession();
|
||||||
|
s.getTransaction().begin();
|
||||||
|
s.persist( title1 );
|
||||||
|
s.persist( dept1 );
|
||||||
|
s.persist( employee1 );
|
||||||
|
s.persist( title2 );
|
||||||
|
s.persist( employee2 );
|
||||||
|
s.getTransaction().commit();
|
||||||
|
s.close();
|
||||||
|
|
||||||
|
s = openSession();
|
||||||
|
s.getTransaction().begin();
|
||||||
|
Department department = (Department) s.createQuery( "select e.department from Employee e inner join e.department" ).uniqueResult();
|
||||||
|
assertEquals( employee1.getDepartment().getDeptName(), department.getDeptName() );
|
||||||
|
s.delete( employee1 );
|
||||||
|
s.delete( title1 );
|
||||||
|
s.delete( department );
|
||||||
|
s.delete( employee2 );
|
||||||
|
s.delete( title2 );
|
||||||
|
s.getTransaction().commit();
|
||||||
|
s.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testExplicitToOneOuterJoin() {
|
||||||
|
final Employee employee1 = new Employee();
|
||||||
|
employee1.setFirstName( "Jane" );
|
||||||
|
employee1.setLastName( "Doe" );
|
||||||
|
final Title title1 = new Title();
|
||||||
|
title1.setDescription( "Jane's description" );
|
||||||
|
final Department dept1 = new Department();
|
||||||
|
dept1.setDeptName( "Jane's department" );
|
||||||
|
employee1.setTitle( title1 );
|
||||||
|
employee1.setDepartment( dept1 );
|
||||||
|
|
||||||
|
final Employee employee2 = new Employee();
|
||||||
|
employee2.setFirstName( "John" );
|
||||||
|
employee2.setLastName( "Doe" );
|
||||||
|
final Title title2 = new Title();
|
||||||
|
title2.setDescription( "John's title" );
|
||||||
|
employee2.setTitle( title2 );
|
||||||
|
|
||||||
|
Session s = openSession();
|
||||||
|
s.getTransaction().begin();
|
||||||
|
s.persist( title1 );
|
||||||
|
s.persist( dept1 );
|
||||||
|
s.persist( employee1 );
|
||||||
|
s.persist( title2 );
|
||||||
|
s.persist( employee2 );
|
||||||
|
s.getTransaction().commit();
|
||||||
|
s.close();
|
||||||
|
s = openSession();
|
||||||
|
s.getTransaction().begin();
|
||||||
|
List list = s.createQuery( "select e.department from Employee e left join e.department" ).list();
|
||||||
|
assertEquals( 2, list.size() );
|
||||||
|
final Department dept;
|
||||||
|
if ( list.get( 0 ) == null ) {
|
||||||
|
dept = (Department) list.get( 1 );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
dept = (Department) list.get( 0 );
|
||||||
|
assertNull( list.get( 1 ) );
|
||||||
|
}
|
||||||
|
assertEquals( dept1.getDeptName(), dept.getDeptName() );
|
||||||
|
s.delete( employee1 );
|
||||||
|
s.delete( title1 );
|
||||||
|
s.delete( dept );
|
||||||
|
s.delete( employee2 );
|
||||||
|
s.delete( title2 );
|
||||||
|
s.getTransaction().commit();
|
||||||
|
s.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testExplicitToOneInnerJoinAndImplicitToOne() {
|
||||||
|
final Employee employee1 = new Employee();
|
||||||
|
employee1.setFirstName( "Jane" );
|
||||||
|
employee1.setLastName( "Doe" );
|
||||||
|
final Title title1 = new Title();
|
||||||
|
title1.setDescription( "Jane's description" );
|
||||||
|
final Department dept1 = new Department();
|
||||||
|
dept1.setDeptName( "Jane's department" );
|
||||||
|
employee1.setTitle( title1 );
|
||||||
|
employee1.setDepartment( dept1 );
|
||||||
|
|
||||||
|
final Employee employee2 = new Employee();
|
||||||
|
employee2.setFirstName( "John" );
|
||||||
|
employee2.setLastName( "Doe" );
|
||||||
|
final Title title2 = new Title();
|
||||||
|
title2.setDescription( "John's title" );
|
||||||
|
employee2.setTitle( title2 );
|
||||||
|
|
||||||
|
Session s = openSession();
|
||||||
|
s.getTransaction().begin();
|
||||||
|
s.persist( title1 );
|
||||||
|
s.persist( dept1 );
|
||||||
|
s.persist( employee1 );
|
||||||
|
s.persist( title2 );
|
||||||
|
s.persist( employee2 );
|
||||||
|
s.getTransaction().commit();
|
||||||
|
s.close();
|
||||||
|
s = openSession();
|
||||||
|
s.getTransaction().begin();
|
||||||
|
Object[] result = (Object[]) s.createQuery(
|
||||||
|
"select e.firstName, e.lastName, e.title.description, e.department from Employee e inner join e.department"
|
||||||
|
).uniqueResult();
|
||||||
|
assertEquals( employee1.getFirstName(), result[0] );
|
||||||
|
assertEquals( employee1.getLastName(), result[1] );
|
||||||
|
assertEquals( employee1.getTitle().getDescription(), result[2] );
|
||||||
|
assertEquals( employee1.getDepartment().getDeptName(), ( (Department) result[3] ).getDeptName() );
|
||||||
|
s.delete( employee1 );
|
||||||
|
s.delete( title1 );
|
||||||
|
s.delete( result[3] );
|
||||||
|
s.delete( employee2 );
|
||||||
|
s.delete( title2 );
|
||||||
|
s.getTransaction().commit();
|
||||||
|
s.close();
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testNestedComponentIsNull() {
|
public void testNestedComponentIsNull() {
|
||||||
// (1) From MapTest originally...
|
// (1) From MapTest originally...
|
||||||
|
@ -1657,6 +1804,134 @@ public class ASTParserLoadingTest extends BaseCoreFunctionalTestCase {
|
||||||
s.close();
|
s.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestForIssue( jiraKey = "HHH-9305")
|
||||||
|
@SuppressWarnings( {"unchecked"})
|
||||||
|
public void testSelectClauseImplicitJoinOrderByJoinedProperty() {
|
||||||
|
Session s = openSession();
|
||||||
|
Transaction t = s.beginTransaction();
|
||||||
|
Zoo zoo = new Zoo();
|
||||||
|
zoo.setName("The Zoo");
|
||||||
|
zoo.setMammals( new HashMap() );
|
||||||
|
zoo.setAnimals( new HashMap() );
|
||||||
|
Mammal plat = new Mammal();
|
||||||
|
plat.setBodyWeight( 11f );
|
||||||
|
plat.setDescription( "Platypus" );
|
||||||
|
plat.setZoo( zoo );
|
||||||
|
plat.setSerialNumber( "plat123" );
|
||||||
|
zoo.getMammals().put( "Platypus", plat );
|
||||||
|
zoo.getAnimals().put("plat123", plat);
|
||||||
|
Zoo otherZoo = new Zoo();
|
||||||
|
otherZoo.setName("The Other Zoo");
|
||||||
|
otherZoo.setMammals( new HashMap() );
|
||||||
|
otherZoo.setAnimals( new HashMap() );
|
||||||
|
Mammal zebra = new Mammal();
|
||||||
|
zebra.setBodyWeight( 110f );
|
||||||
|
zebra.setDescription( "Zebra" );
|
||||||
|
zebra.setZoo( otherZoo );
|
||||||
|
zebra.setSerialNumber( "zebra123" );
|
||||||
|
otherZoo.getMammals().put( "Zebra", zebra );
|
||||||
|
otherZoo.getAnimals().put("zebra123", zebra);
|
||||||
|
Mammal elephant = new Mammal();
|
||||||
|
elephant.setBodyWeight( 550f );
|
||||||
|
elephant.setDescription( "Elephant" );
|
||||||
|
elephant.setZoo( otherZoo );
|
||||||
|
elephant.setSerialNumber( "elephant123" );
|
||||||
|
otherZoo.getMammals().put( "Elephant", elephant );
|
||||||
|
otherZoo.getAnimals().put( "elephant123", elephant );
|
||||||
|
s.persist( plat );
|
||||||
|
s.persist(zoo);
|
||||||
|
s.persist( zebra );
|
||||||
|
s.persist( elephant );
|
||||||
|
s.persist( otherZoo );
|
||||||
|
s.flush();
|
||||||
|
s.clear();
|
||||||
|
Query q = s.createQuery("select a.zoo from Animal a where a.zoo is not null order by a.zoo.name");
|
||||||
|
Type type = q.getReturnTypes()[0];
|
||||||
|
assertTrue( type instanceof ManyToOneType );
|
||||||
|
assertEquals( ( (ManyToOneType) type ).getAssociatedEntityName(), "org.hibernate.test.hql.Zoo" );
|
||||||
|
List<Zoo> zoos = (List<Zoo>) q.list();
|
||||||
|
assertEquals( 3, zoos.size() );
|
||||||
|
assertEquals( otherZoo.getName(), zoos.get( 0 ).getName() );
|
||||||
|
assertEquals( 2, zoos.get( 0 ).getMammals().size() );
|
||||||
|
assertEquals( 2, zoos.get( 0 ).getAnimals().size() );
|
||||||
|
assertSame( zoos.get( 0 ), zoos.get( 1 ) );
|
||||||
|
assertEquals( zoo.getName(), zoos.get( 2 ).getName() );
|
||||||
|
assertEquals( 1, zoos.get( 2 ).getMammals().size() );
|
||||||
|
assertEquals( 1, zoos.get( 2 ).getAnimals().size() );
|
||||||
|
s.clear();
|
||||||
|
s.delete(plat);
|
||||||
|
s.delete( zebra );
|
||||||
|
s.delete( elephant );
|
||||||
|
s.delete(zoo);
|
||||||
|
s.delete( otherZoo );
|
||||||
|
t.commit();
|
||||||
|
s.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@SuppressWarnings( {"unchecked"})
|
||||||
|
public void testSelectClauseDistinctImplicitJoinOrderByJoinedProperty() {
|
||||||
|
Session s = openSession();
|
||||||
|
Transaction t = s.beginTransaction();
|
||||||
|
Zoo zoo = new Zoo();
|
||||||
|
zoo.setName("The Zoo");
|
||||||
|
zoo.setMammals( new HashMap() );
|
||||||
|
zoo.setAnimals( new HashMap() );
|
||||||
|
Mammal plat = new Mammal();
|
||||||
|
plat.setBodyWeight( 11f );
|
||||||
|
plat.setDescription( "Platypus" );
|
||||||
|
plat.setZoo( zoo );
|
||||||
|
plat.setSerialNumber( "plat123" );
|
||||||
|
zoo.getMammals().put( "Platypus", plat );
|
||||||
|
zoo.getAnimals().put("plat123", plat);
|
||||||
|
Zoo otherZoo = new Zoo();
|
||||||
|
otherZoo.setName("The Other Zoo");
|
||||||
|
otherZoo.setMammals( new HashMap() );
|
||||||
|
otherZoo.setAnimals( new HashMap() );
|
||||||
|
Mammal zebra = new Mammal();
|
||||||
|
zebra.setBodyWeight( 110f );
|
||||||
|
zebra.setDescription( "Zebra" );
|
||||||
|
zebra.setZoo( otherZoo );
|
||||||
|
zebra.setSerialNumber( "zebra123" );
|
||||||
|
otherZoo.getMammals().put( "Zebra", zebra );
|
||||||
|
otherZoo.getAnimals().put("zebra123", zebra);
|
||||||
|
Mammal elephant = new Mammal();
|
||||||
|
elephant.setBodyWeight( 550f );
|
||||||
|
elephant.setDescription( "Elephant" );
|
||||||
|
elephant.setZoo( otherZoo );
|
||||||
|
elephant.setSerialNumber( "elephant123" );
|
||||||
|
otherZoo.getMammals().put( "Elephant", elephant );
|
||||||
|
otherZoo.getAnimals().put( "elephant123", elephant );
|
||||||
|
s.persist( plat );
|
||||||
|
s.persist(zoo);
|
||||||
|
s.persist( zebra );
|
||||||
|
s.persist( elephant );
|
||||||
|
s.persist( otherZoo );
|
||||||
|
s.flush();
|
||||||
|
s.clear();
|
||||||
|
Query q = s.createQuery("select distinct a.zoo from Animal a where a.zoo is not null order by a.zoo.name");
|
||||||
|
Type type = q.getReturnTypes()[0];
|
||||||
|
assertTrue( type instanceof ManyToOneType );
|
||||||
|
assertEquals( ( (ManyToOneType) type ).getAssociatedEntityName(), "org.hibernate.test.hql.Zoo" );
|
||||||
|
List<Zoo> zoos = (List<Zoo>) q.list();
|
||||||
|
assertEquals( 2, zoos.size() );
|
||||||
|
assertEquals( otherZoo.getName(), zoos.get( 0 ).getName() );
|
||||||
|
assertEquals( 2, zoos.get( 0 ).getMammals().size() );
|
||||||
|
assertEquals( 2, zoos.get( 0 ).getAnimals().size() );
|
||||||
|
assertEquals( zoo.getName(), zoos.get( 1 ).getName() );
|
||||||
|
assertEquals( 1, zoos.get( 1 ).getMammals().size() );
|
||||||
|
assertEquals( 1, zoos.get( 1 ).getAnimals().size() );
|
||||||
|
s.clear();
|
||||||
|
s.delete(plat);
|
||||||
|
s.delete( zebra );
|
||||||
|
s.delete( elephant );
|
||||||
|
s.delete(zoo);
|
||||||
|
s.delete( otherZoo );
|
||||||
|
t.commit();
|
||||||
|
s.close();
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@SuppressWarnings( {"unchecked"})
|
@SuppressWarnings( {"unchecked"})
|
||||||
public void testSelectClauseImplicitJoinWithIterate() {
|
public void testSelectClauseImplicitJoinWithIterate() {
|
||||||
|
@ -2770,6 +3045,118 @@ public class ASTParserLoadingTest extends BaseCoreFunctionalTestCase {
|
||||||
destroyTestBaseData();
|
destroyTestBaseData();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestForIssue( jiraKey = "HHH-9305")
|
||||||
|
public void testDynamicInstantiationWithToOneQueries() throws Exception {
|
||||||
|
final Employee employee1 = new Employee();
|
||||||
|
employee1.setFirstName( "Jane" );
|
||||||
|
employee1.setLastName( "Doe" );
|
||||||
|
final Title title1 = new Title();
|
||||||
|
title1.setDescription( "Jane's description" );
|
||||||
|
final Department dept1 = new Department();
|
||||||
|
dept1.setDeptName( "Jane's department" );
|
||||||
|
employee1.setTitle( title1 );
|
||||||
|
employee1.setDepartment( dept1 );
|
||||||
|
|
||||||
|
final Employee employee2 = new Employee();
|
||||||
|
employee2.setFirstName( "John" );
|
||||||
|
employee2.setLastName( "Doe" );
|
||||||
|
final Title title2 = new Title();
|
||||||
|
title2.setDescription( "John's title" );
|
||||||
|
employee2.setTitle( title2 );
|
||||||
|
|
||||||
|
Session s = openSession();
|
||||||
|
s.getTransaction().begin();
|
||||||
|
s.persist( title1 );
|
||||||
|
s.persist( dept1 );
|
||||||
|
s.persist( employee1 );
|
||||||
|
s.persist( title2 );
|
||||||
|
s.persist( employee2 );
|
||||||
|
s.getTransaction().commit();
|
||||||
|
s.close();
|
||||||
|
|
||||||
|
// There are 2 to-one associations: Employee.title and Employee.department.
|
||||||
|
// It appears that adding an explicit join for one of these to-one associations keeps ANSI joins
|
||||||
|
// at the beginning of the FROM clause, avoiding failures on DBs that cannot handle cross joins
|
||||||
|
// interleaved with ANSI joins (e.g., PostgreSql).
|
||||||
|
|
||||||
|
s = openSession();
|
||||||
|
s.getTransaction().begin();
|
||||||
|
List results = session.createQuery(
|
||||||
|
"select new Employee(e.id, e.lastName, e.title.id, e.title.description, e.department, e.firstName) from Employee e inner join e.title"
|
||||||
|
).list();
|
||||||
|
assertEquals( "Incorrect result size", 1, results.size() );
|
||||||
|
assertClassAssignability( results.get( 0 ).getClass(), Employee.class );
|
||||||
|
results = session.createQuery(
|
||||||
|
"select new Employee(e.id, e.lastName, t.id, t.description, e.department, e.firstName) from Employee e inner join e.title t"
|
||||||
|
).list();
|
||||||
|
assertEquals( "Incorrect result size", 1, results.size() );
|
||||||
|
assertClassAssignability( results.get( 0 ).getClass(), Employee.class );
|
||||||
|
results = session.createQuery(
|
||||||
|
"select new Employee(e.id, e.lastName, e.title.id, e.title.description, e.department, e.firstName) from Employee e inner join e.department"
|
||||||
|
).list();
|
||||||
|
assertEquals( "Incorrect result size", 1, results.size() );
|
||||||
|
assertClassAssignability( results.get( 0 ).getClass(), Employee.class );
|
||||||
|
results = session.createQuery(
|
||||||
|
"select new Employee(e.id, e.lastName, e.title.id, e.title.description, d, e.firstName) from Employee e inner join e.department d"
|
||||||
|
).list();
|
||||||
|
assertEquals( "Incorrect result size", 1, results.size() );
|
||||||
|
assertClassAssignability( results.get( 0 ).getClass(), Employee.class );
|
||||||
|
results = session.createQuery(
|
||||||
|
"select new Employee(e.id, e.lastName, e.title.id, e.title.description, e.department, e.firstName) from Employee e left outer join e.department"
|
||||||
|
).list();
|
||||||
|
assertEquals( "Incorrect result size", 2, results.size() );
|
||||||
|
assertClassAssignability( results.get( 0 ).getClass(), Employee.class );
|
||||||
|
results = session.createQuery(
|
||||||
|
"select new Employee(e.id, e.lastName, e.title.id, e.title.description, d, e.firstName) from Employee e left outer join e.department d"
|
||||||
|
).list();
|
||||||
|
assertEquals( "Incorrect result size", 2, results.size() );
|
||||||
|
assertClassAssignability( results.get( 0 ).getClass(), Employee.class );
|
||||||
|
results = session.createQuery(
|
||||||
|
"select new Employee(e.id, e.lastName, e.title.id, e.title.description, e.department, e.firstName) from Employee e left outer join e.department inner join e.title"
|
||||||
|
).list();
|
||||||
|
assertEquals( "Incorrect result size", 2, results.size() );
|
||||||
|
assertClassAssignability( results.get( 0 ).getClass(), Employee.class );
|
||||||
|
results = session.createQuery(
|
||||||
|
"select new Employee(e.id, e.lastName, t.id, t.description, d, e.firstName) from Employee e left outer join e.department d inner join e.title t"
|
||||||
|
).list();
|
||||||
|
assertEquals( "Incorrect result size", 2, results.size() );
|
||||||
|
assertClassAssignability( results.get( 0 ).getClass(), Employee.class );
|
||||||
|
results = session.createQuery(
|
||||||
|
"select new Employee(e.id, e.lastName, e.title.id, e.title.description, e.department, e.firstName) from Employee e left outer join e.department left outer join e.title"
|
||||||
|
).list();
|
||||||
|
assertEquals( "Incorrect result size", 2, results.size() );
|
||||||
|
assertClassAssignability( results.get( 0 ).getClass(), Employee.class );
|
||||||
|
results = session.createQuery(
|
||||||
|
"select new Employee(e.id, e.lastName, t.id, t.description, d, e.firstName) from Employee e left outer join e.department d left outer join e.title t"
|
||||||
|
).list();
|
||||||
|
assertEquals( "Incorrect result size", 2, results.size() );
|
||||||
|
assertClassAssignability( results.get( 0 ).getClass(), Employee.class );
|
||||||
|
results = session.createQuery(
|
||||||
|
"select new Employee(e.id, e.lastName, e.title.id, e.title.description, e.department, e.firstName) from Employee e left outer join e.department order by e.title.description"
|
||||||
|
).list();
|
||||||
|
assertEquals( "Incorrect result size", 2, results.size() );
|
||||||
|
assertClassAssignability( results.get( 0 ).getClass(), Employee.class );
|
||||||
|
results = session.createQuery(
|
||||||
|
"select new Employee(e.id, e.lastName, e.title.id, e.title.description, e.department, e.firstName) from Employee e left outer join e.department d order by e.title.description"
|
||||||
|
).list();
|
||||||
|
assertEquals( "Incorrect result size", 2, results.size() );
|
||||||
|
assertClassAssignability( results.get( 0 ).getClass(), Employee.class );
|
||||||
|
s.getTransaction().commit();
|
||||||
|
|
||||||
|
s.close();
|
||||||
|
|
||||||
|
s = openSession();
|
||||||
|
s.getTransaction().begin();
|
||||||
|
s.delete( employee1 );
|
||||||
|
s.delete( title1 );
|
||||||
|
s.delete( dept1 );
|
||||||
|
s.delete( employee2 );
|
||||||
|
s.delete( title2 );
|
||||||
|
s.getTransaction().commit();
|
||||||
|
s.close();
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@SuppressWarnings( {"UnusedAssignment"})
|
@SuppressWarnings( {"UnusedAssignment"})
|
||||||
public void testCachedJoinedAndJoinFetchedManyToOne() throws Exception {
|
public void testCachedJoinedAndJoinFetchedManyToOne() throws Exception {
|
||||||
|
|
|
@ -0,0 +1,58 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* Copyright (c) 2014, Red Hat Inc. or third-party contributors as
|
||||||
|
* indicated by the @author tags or express copyright attribution
|
||||||
|
* statements applied by the authors. All third-party contributions are
|
||||||
|
* distributed under license by Red Hat Inc.
|
||||||
|
*
|
||||||
|
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||||
|
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||||
|
* Lesser General Public License, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this distribution; if not, write to:
|
||||||
|
* Free Software Foundation, Inc.
|
||||||
|
* 51 Franklin Street, Fifth Floor
|
||||||
|
* Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
package org.hibernate.test.hql;
|
||||||
|
|
||||||
|
import javax.persistence.Column;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.GeneratedValue;
|
||||||
|
import javax.persistence.GenerationType;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(name="department")
|
||||||
|
public class Department implements java.io.Serializable {
|
||||||
|
private Integer deptNo;
|
||||||
|
private String deptName;
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy=GenerationType.IDENTITY)
|
||||||
|
@Column(name="id_dep")
|
||||||
|
public Integer getDeptNo() {
|
||||||
|
return this.deptNo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDeptNo(Integer deptNo) {
|
||||||
|
this.deptNo = deptNo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDeptName() {
|
||||||
|
return this.deptName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDeptName(String deptName) {
|
||||||
|
this.deptName = deptName;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,107 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* Copyright (c) 2014, Red Hat Inc. or third-party contributors as
|
||||||
|
* indicated by the @author tags or express copyright attribution
|
||||||
|
* statements applied by the authors. All third-party contributions are
|
||||||
|
* distributed under license by Red Hat Inc.
|
||||||
|
*
|
||||||
|
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||||
|
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||||
|
* Lesser General Public License, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this distribution; if not, write to:
|
||||||
|
* Free Software Foundation, Inc.
|
||||||
|
* 51 Franklin Street, Fifth Floor
|
||||||
|
* Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
package org.hibernate.test.hql;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
import javax.persistence.Column;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.FetchType;
|
||||||
|
import javax.persistence.GeneratedValue;
|
||||||
|
import javax.persistence.GenerationType;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.JoinColumn;
|
||||||
|
import javax.persistence.ManyToOne;
|
||||||
|
import javax.persistence.OneToOne;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(name="employee")
|
||||||
|
public class Employee implements Serializable {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy=GenerationType.IDENTITY)
|
||||||
|
@Column(name="id_emp")
|
||||||
|
private Integer id;
|
||||||
|
|
||||||
|
private String firstName;
|
||||||
|
private String lastName;
|
||||||
|
|
||||||
|
@OneToOne
|
||||||
|
@JoinColumn(name="id_title")
|
||||||
|
private Title title;
|
||||||
|
|
||||||
|
@ManyToOne(fetch=FetchType.LAZY)
|
||||||
|
@JoinColumn(name="id_depto")
|
||||||
|
private Department department;
|
||||||
|
|
||||||
|
public Employee() {}
|
||||||
|
|
||||||
|
public Employee(Integer _id, String _lastName, Integer _idTitle, String _descriptionTitle, Department _dept, String _fname) {
|
||||||
|
setId(_id);
|
||||||
|
setLastName(_lastName);
|
||||||
|
Title _title = new Title();
|
||||||
|
_title.setId(_idTitle);
|
||||||
|
_title.setDescription(_descriptionTitle);
|
||||||
|
setTitle(_title);
|
||||||
|
setDepartment(_dept);
|
||||||
|
setFirstName(_fname);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
public void setId(Integer id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
public String getFirstName() {
|
||||||
|
return firstName;
|
||||||
|
}
|
||||||
|
public void setFirstName(String firstName) {
|
||||||
|
this.firstName = firstName;
|
||||||
|
}
|
||||||
|
public String getLastName() {
|
||||||
|
return lastName;
|
||||||
|
}
|
||||||
|
public void setLastName(String lastName) {
|
||||||
|
this.lastName = lastName;
|
||||||
|
}
|
||||||
|
public Title getTitle() {
|
||||||
|
return title;
|
||||||
|
}
|
||||||
|
public void setTitle(Title title) {
|
||||||
|
this.title = title;
|
||||||
|
}
|
||||||
|
public Department getDepartment() {
|
||||||
|
return department;
|
||||||
|
}
|
||||||
|
public void setDepartment(Department department) {
|
||||||
|
this.department = department;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,61 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* Copyright (c) 2014, Red Hat Inc. or third-party contributors as
|
||||||
|
* indicated by the @author tags or express copyright attribution
|
||||||
|
* statements applied by the authors. All third-party contributions are
|
||||||
|
* distributed under license by Red Hat Inc.
|
||||||
|
*
|
||||||
|
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||||
|
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||||
|
* Lesser General Public License, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this distribution; if not, write to:
|
||||||
|
* Free Software Foundation, Inc.
|
||||||
|
* 51 Franklin Street, Fifth Floor
|
||||||
|
* Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
package org.hibernate.test.hql;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
import javax.persistence.Column;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.GeneratedValue;
|
||||||
|
import javax.persistence.GenerationType;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(name="title")
|
||||||
|
public class Title implements Serializable {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy=GenerationType.IDENTITY)
|
||||||
|
@Column(name="id_title")
|
||||||
|
private Integer id;
|
||||||
|
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
public Integer getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
public void setId(Integer id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
public String getDescription() {
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
public void setDescription(String description) {
|
||||||
|
this.description = description;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue