/*
* 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.test.hql;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
import org.junit.Test;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.ManyToMany;
import javax.persistence.MappedSuperclass;
import javax.persistence.Table;
import javax.persistence.Version;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* Implementation of WithClauseTest.
*
* @author Steve Ebersole
*/
public class WithClauseJoinRewriteTest extends BaseCoreFunctionalTestCase {
@Override
protected Class[] getAnnotatedClasses() {
return new Class[]{
AbstractObject.class,
AbstractConfigurationObject.class,
ConfigurationObject.class
};
}
@Test
@TestForIssue(jiraKey = "HHH-11230")
public void testInheritanceReAliasing() {
Session s = openSession();
Transaction tx = s.beginTransaction();
// Just assert that the query is successful
List<Object[]> results = s.createQuery(
"SELECT usedBy.id, usedBy.name, COUNT(inverse.id) " +
"FROM " + AbstractConfigurationObject.class.getName() + " config " +
"INNER JOIN config.usedBy usedBy " +
"LEFT JOIN usedBy.uses inverse ON inverse.id = config.id " +
"WHERE config.id = 0 " +
"GROUP BY usedBy.id, usedBy.name",
Object[].class
).getResultList();
tx.commit();
s.close();
}
@Entity
@Table( name = "config" )
@Inheritance( strategy = InheritanceType.JOINED )
public static abstract class AbstractConfigurationObject<T extends ConfigurationObject> extends AbstractObject {
private String name;
private Set<ConfigurationObject> uses = new HashSet<>();
private Set<ConfigurationObject> usedBy = new HashSet<>();
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@ManyToMany( targetEntity = AbstractConfigurationObject.class, fetch = FetchType.LAZY, cascade = {} )
public Set<ConfigurationObject> getUses () {
return uses;
}
public void setUses(Set<ConfigurationObject> uses) {
this.uses = uses;
}
@ManyToMany ( targetEntity = AbstractConfigurationObject.class, fetch = FetchType.LAZY, mappedBy = "uses", cascade = {} )
public Set<ConfigurationObject> getUsedBy () {
return usedBy;
}
public void setUsedBy(Set<ConfigurationObject> usedBy) {
this.usedBy = usedBy;
}
}
@Entity
@Table( name = "config_config" )
public static class ConfigurationObject extends AbstractConfigurationObject<ConfigurationObject> {
}
@MappedSuperclass
public static class AbstractObject {
private Long id;
private Long version;
@Id
@GeneratedValue
public Long getId () {
return id;
}
public void setId(Long id) {
this.id = id;
}
@Version
@Column( nullable = false )
public Long getVersion () {
return version;
}
public void setVersion(Long version) {
this.version = version;
}
}
}