package org.hibernate.test.filter;
import javax.persistence.*;
import javax.persistence.Entity;
import javax.persistence.Table;
import java.io.Serializable;
import java.util.Arrays;
import java.util.List;
import org.hibernate.Criteria;
import org.hibernate.annotations.*;
import org.hibernate.criterion.*;
import org.junit.After;
import org.junit.Test;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
import static org.hamcrest.core.Is.is;
import static org.junit.Assert.assertThat;
import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate;
public class CriteriaQueryWithAppliedFilterSQLServerTest {
private final static CriteriaQueryWithAppliedFilterTest.Identifier STUDENT_ID = new CriteriaQueryWithAppliedFilterTest.Identifier( 2, new CriteriaQueryWithAppliedFilterTest.Identifier2( 4, 5L ) );
private final static CriteriaQueryWithAppliedFilterTest.Identifier OU_ID = new CriteriaQueryWithAppliedFilterTest.Identifier( 1, new CriteriaQueryWithAppliedFilterTest.Identifier2( 4, 5L ) );
@Override
protected Class<?>[] getAnnotatedClasses() {
return new Class[] {CriteriaQueryWithAppliedFilterTest.Student.class, CriteriaQueryWithAppliedFilterTest.OrganisationUnit.class};
}
@Override
protected void prepareTest() throws Exception {
doInHibernate( this::sessionFactory, session -> {
final CriteriaQueryWithAppliedFilterTest.OrganisationUnit ou = new CriteriaQueryWithAppliedFilterTest.OrganisationUnit(1);
session.save(ou);
final CriteriaQueryWithAppliedFilterTest.Student student = new CriteriaQueryWithAppliedFilterTest.Student();
student.setId( STUDENT_ID );
student.setTheId(1);
student.setOrganisationUnit(ou);
student.setName( "dre" );
student.setStatus( "active" );
student.setAge( 21 );
student.setAddress( new CriteriaQueryWithAppliedFilterTest.Address( "London", "Lollard St" ) );
session.save( student );
final CriteriaQueryWithAppliedFilterTest.Student student2 = new CriteriaQueryWithAppliedFilterTest.Student();
student2.setId( new CriteriaQueryWithAppliedFilterTest.Identifier( 4, new CriteriaQueryWithAppliedFilterTest.Identifier2( 4, 6L ) ) );
student2.setTheId(2);
student.setOrganisationUnit(ou);
student2.setName( "Livia" );
student2.setStatus( "active" );
student2.setAge( 27 );
student2.setAddress( new CriteriaQueryWithAppliedFilterTest.Address( "London", "Oxford St" ) );
session.save( student2 );
});
}
@After
public void tearDown() {
doInHibernate( this::sessionFactory, session -> {
session.createQuery( "delete from Student" ).executeUpdate();
} );
}
@Test
public void testGenialCompletex() {
doInHibernate(this::sessionFactory, session -> {
session.enableFilter( "statusFilter" ).setParameter( "status", "active" );
int page = 1;
int pageSize = 10;
final DetachedCriteria theCriteria = DetachedCriteria.forClass(CriteriaQueryWithAppliedFilterTest.Student.class,"s");
theCriteria.setProjection(Projections.distinct(Projections.property("s.theId")));
final Criteria outer = session.createCriteria(CriteriaQueryWithAppliedFilterTest.Student.class, "d");
session.enableFilter(CriteriaQueryWithAppliedFilterTest.Auditable.OU_FILTER);
org.hibernate.Filter ouFilter = session.enableFilter(CriteriaQueryWithAppliedFilterTest.Auditable.OU_FILTER);
ouFilter.setParameterList(CriteriaQueryWithAppliedFilterTest.Auditable.OU_FILTER_PARAM, Arrays.asList(1,2));
outer.add(Subqueries.propertyIn("d.theId",theCriteria));
outer.setMaxResults(10);
outer.setFirstResult((page -1 ) * pageSize);
final List list = outer.list();
assertThat(list.size(), is (2));
});
}
public static class Auditable {
public static final String OU_CONDITIONS = "(organisationUnit_id IN (:ous) OR organisationUnit_id IS NULL)";
public static final String OU_FILTER = "filterByOus";
public static final String OU_FILTER_PARAM = "ous";
}
@Entity(name = "OrganisationUnit")
@Table(name = "ORGANISATIONUNIT")
public static class OrganisationUnit {
public OrganisationUnit() {}
public OrganisationUnit(int ou) {
this.id = ou;
}
@Id
private int id;
}
@FilterDef(
name = "statusFilter",
parameters = {
@ParamDef(
name = "status", type = "string"
)
}
)
@FilterDef(name = CriteriaQueryWithAppliedFilterTest.Auditable.OU_FILTER, parameters = @ParamDef(name = CriteriaQueryWithAppliedFilterTest.Auditable.OU_FILTER_PARAM, type = "integer"))
@Filter(name = "statusFilter", condition = "STATUS = :status ")
@Filter(name = CriteriaQueryWithAppliedFilterTest.Auditable.OU_FILTER, condition = CriteriaQueryWithAppliedFilterTest.Auditable.OU_CONDITIONS)
@Entity(name = "Student")
@Table(name = "STUDENT")
public static class Student extends CriteriaQueryWithAppliedFilterTest.Auditable {
@ManyToOne(fetch = FetchType.LAZY)
private CriteriaQueryWithAppliedFilterTest.OrganisationUnit organisationUnit;
@EmbeddedId
private CriteriaQueryWithAppliedFilterTest.Identifier id;
private int theId;
private String name;
private int age;
@Column(name = "STATUS")
private String status;
@Embedded
private CriteriaQueryWithAppliedFilterTest.Address address;
public void setOrganisationUnit(CriteriaQueryWithAppliedFilterTest.OrganisationUnit organisationUnit) {
this.organisationUnit = organisationUnit;
}
public void setTheId(int id) {
this.theId = id;
}
public void setId(CriteriaQueryWithAppliedFilterTest.Identifier id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
public void setStatus(String status) {
this.status = status;
}
public void setAge(int age) {
this.age = age;
}
public void setAddress(CriteriaQueryWithAppliedFilterTest.Address address) {
this.address = address;
}
}
@Embeddable
public static class Identifier implements Serializable {
private Integer id1;
@Embedded
private CriteriaQueryWithAppliedFilterTest.Identifier2 id2;
public Identifier() {
}
public Identifier(Integer id1, CriteriaQueryWithAppliedFilterTest.Identifier2 id2) {
this.id1 = id1;
this.id2 = id2;
}
}
@Embeddable
public static class Identifier2 implements Serializable {
private Integer id3;
private Long id4;
public Identifier2() {
}
public Identifier2(Integer id1, Long id2) {
this.id3 = id1;
this.id4 = id2;
}
}
@Embeddable
public static class Address implements Serializable {
private String city;
private String street;
public Address() {
}
public Address(String city, String street) {
this.city = city;
this.street = street;
}
}
}