/* * Copyright 2014 - 2017 Blazebit. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.blazebit.persistence.criteria; import com.blazebit.persistence.CriteriaBuilder; import com.blazebit.persistence.criteria.impl.BlazeCriteria; import com.blazebit.persistence.testsuite.AbstractCoreTest; import com.blazebit.persistence.testsuite.base.category.NoDatanucleus; import com.blazebit.persistence.testsuite.base.category.NoEclipselink; import com.blazebit.persistence.testsuite.entity.*; import com.googlecode.catchexception.CatchException; import org.junit.Test; import org.junit.experimental.categories.Category; import javax.persistence.Tuple; import static org.junit.Assert.assertEquals; /** * * @author Christian Beikov * @since 1.2.0 */ public class TreatTest extends AbstractCoreTest { @Override protected Class<?>[] getEntityClasses() { return new Class<?>[] { IntIdEntity.class, PolymorphicBase.class, PolymorphicSub1.class, PolymorphicSub2.class }; } @Test public void selectTreatedRoot() { BlazeCriteriaQuery<PolymorphicSub1> cq = BlazeCriteria.get(em, cbf, PolymorphicSub1.class); BlazeCriteriaBuilder cb = cq.getCriteriaBuilder(); BlazeRoot<PolymorphicBase> root = cq.from(PolymorphicBase.class, "base"); cq.select(cb.treat(root, PolymorphicSub1.class)); CriteriaBuilder<?> criteriaBuilder = cq.createCriteriaBuilder(); assertEquals("SELECT base FROM PolymorphicBase base WHERE TYPE(base) = PolymorphicSub1", criteriaBuilder.getQueryString()); } @Test public void multipleTreatedRootInWhere() { BlazeCriteriaQuery<PolymorphicBase> cq = BlazeCriteria.get(em, cbf, PolymorphicBase.class); BlazeCriteriaBuilder cb = cq.getCriteriaBuilder(); BlazeRoot<PolymorphicBase> root = cq.from(PolymorphicBase.class, "base"); cq.where(cb.or( cb.treat(root, PolymorphicSub1.class).get(PolymorphicSub1_.sub1Value).isNotNull(), cb.treat(root, PolymorphicSub2.class).get(PolymorphicSub2_.sub2Value).isNotNull() )); CriteriaBuilder<?> criteriaBuilder = cq.createCriteriaBuilder(); String whereFragment = ""; whereFragment += treatRootWhereFragment("base", PolymorphicSub1.class, ".sub1Value IS NOT NULL", false); whereFragment += " OR " + treatRootWhereFragment("base", PolymorphicSub2.class, ".sub2Value IS NOT NULL", false); assertEquals("SELECT base FROM PolymorphicBase base" + " WHERE " + whereFragment, criteriaBuilder.getQueryString()); } @Test public void treatRoot() { BlazeCriteriaQuery<Integer> cq = BlazeCriteria.get(em, cbf, Integer.class); BlazeCriteriaBuilder cb = cq.getCriteriaBuilder(); BlazeRoot<PolymorphicBase> root = cq.from(PolymorphicBase.class, "base"); cq.select(cb.treat(root, PolymorphicSub1.class).get(PolymorphicSub1_.sub1Value)); cq.where(cb.treat(root, PolymorphicSub1.class).get("sub1Value").isNotNull()); CriteriaBuilder<?> criteriaBuilder = cq.createCriteriaBuilder(); String whereFragment = treatRootWhereFragment("base", PolymorphicSub1.class, ".sub1Value IS NOT NULL", false); assertEquals("SELECT " + treatRoot("base", PolymorphicSub1.class, "sub1Value") + " FROM PolymorphicBase base WHERE " + whereFragment, criteriaBuilder.getQueryString()); } @Test // Eclipselink does not support dereferencing of TREAT join path elements @Category({ NoDatanucleus.class, NoEclipselink.class }) public void treatRootJoin() { BlazeCriteriaQuery<PolymorphicBase> cq = BlazeCriteria.get(em, cbf, PolymorphicBase.class); BlazeCriteriaBuilder cb = cq.getCriteriaBuilder(); BlazeRoot<PolymorphicBase> root = cq.from(PolymorphicBase.class, "base"); BlazeJoin<PolymorphicSub1, PolymorphicBase> join = cb.treat(root, PolymorphicSub1.class).join(PolymorphicSub1_.parent1, "p1"); cq.select(join); CriteriaBuilder<?> criteriaBuilder = cq.createCriteriaBuilder(); assertEquals("SELECT p1 FROM PolymorphicBase base" + " JOIN " + treatRootJoin("base", PolymorphicSub1.class, "parent1") + " p1", criteriaBuilder.getQueryString()); } @Test public void multipleDistinctTreatJoin() { BlazeCriteriaQuery<PolymorphicBase> cq = BlazeCriteria.get(em, cbf, PolymorphicBase.class); BlazeCriteriaBuilder cb = cq.getCriteriaBuilder(); BlazeRoot<PolymorphicBase> root = cq.from(PolymorphicBase.class, "base"); BlazeJoin<PolymorphicBase, PolymorphicBase> join = root.join(PolymorphicBase_.parent, "p1"); cb.treat(join, PolymorphicSub1.class); CatchException.verifyException(cb, IllegalArgumentException.class).treat(join, PolymorphicSub2.class); } @Test public void treatJoin() { BlazeCriteriaQuery<Tuple> cq = BlazeCriteria.get(em, cbf, Tuple.class); BlazeCriteriaBuilder cb = cq.getCriteriaBuilder(); BlazeRoot<PolymorphicBase> root = cq.from(PolymorphicBase.class, "base"); BlazeJoin<PolymorphicBase, PolymorphicSub1> treatedJoin = cb.treat(root.join(PolymorphicBase_.parent, "parent"), PolymorphicSub1.class); BlazeJoin<PolymorphicBase, PolymorphicSub2> treatedJoin2 = cb.treat(root.join(PolymorphicBase_.parent, "parent2"), PolymorphicSub2.class); BlazeListJoin<PolymorphicBase, PolymorphicSub1> treatedListJoin = cb.treat(root.join(PolymorphicBase_.list, "list"), PolymorphicSub1.class); BlazeSetJoin<PolymorphicBase, PolymorphicSub1> treatedSetJoin = cb.treat(root.join(PolymorphicBase_.children, "child"), PolymorphicSub1.class); BlazeMapJoin<PolymorphicBase, String, PolymorphicSub1> treatedMapJoin = cb.treat(root.join(PolymorphicBase_.map, "map"), PolymorphicSub1.class); cq.multiselect( treatedJoin.get(PolymorphicSub1_.sub1Value), treatedListJoin.get(PolymorphicSub1_.sub1Value), treatedSetJoin.get(PolymorphicSub1_.sub1Value), treatedMapJoin.get(PolymorphicSub1_.sub1Value), treatedListJoin.index(), treatedMapJoin.key() ); CriteriaBuilder<?> criteriaBuilder = cq.createCriteriaBuilder(); String whereFragment = null; whereFragment = treatJoinWhereFragment(PolymorphicBase.class, "children", "child", PolymorphicSub1.class, com.blazebit.persistence.JoinType.INNER, whereFragment); whereFragment = treatJoinWhereFragment(PolymorphicBase.class, "list", "list", PolymorphicSub1.class, com.blazebit.persistence.JoinType.INNER, whereFragment); whereFragment = treatJoinWhereFragment(PolymorphicBase.class, "map", "map", PolymorphicSub1.class, com.blazebit.persistence.JoinType.INNER, whereFragment); whereFragment = treatJoinWhereFragment(PolymorphicBase.class, "parent", "parent", PolymorphicSub1.class, com.blazebit.persistence.JoinType.INNER, whereFragment); whereFragment = treatJoinWhereFragment(PolymorphicBase.class, "parent2", "parent2", PolymorphicSub2.class, com.blazebit.persistence.JoinType.INNER, whereFragment); assertEquals("SELECT parent.sub1Value, list.sub1Value, child.sub1Value, " + joinAliasValue("map", "sub1Value") + ", INDEX(list), KEY(map)" + " FROM PolymorphicBase base" + " JOIN " + treatJoin("base.children", PolymorphicSub1.class) + " child" + " JOIN " + treatJoin("base.list", PolymorphicSub1.class) + " list" + " JOIN " + treatJoin("base.map", PolymorphicSub1.class) + " map" + " JOIN " + treatJoin("base.parent", PolymorphicSub1.class) + " parent" + " JOIN " + treatJoin("base.parent", PolymorphicSub2.class) + " parent2" + whereFragment, criteriaBuilder.getQueryString()); } @Test // Eclipselink does not support dereferencing of TREAT join path elements @Category({ NoDatanucleus.class, NoEclipselink.class }) public void joinTreatedJoinWithOnClause() { BlazeCriteriaQuery<Tuple> cq = BlazeCriteria.get(em, cbf, Tuple.class); BlazeCriteriaBuilder cb = cq.getCriteriaBuilder(); BlazeRoot<PolymorphicBase> root = cq.from(PolymorphicBase.class, "base"); BlazeJoin<PolymorphicBase, PolymorphicSub1> treatedJoin = cb.treat(root.join(PolymorphicBase_.parent, "parent"), PolymorphicSub1.class); BlazeJoin<PolymorphicBase, PolymorphicSub2> treatedJoin2 = cb.treat(root.join(PolymorphicBase_.parent, "parent2"), PolymorphicSub2.class); BlazeListJoin<PolymorphicBase, PolymorphicSub1> treatedListJoin = cb.treat(root.join(PolymorphicBase_.list, "list"), PolymorphicSub1.class); BlazeSetJoin<PolymorphicBase, PolymorphicSub1> treatedSetJoin = cb.treat(root.join(PolymorphicBase_.children, "child"), PolymorphicSub1.class); BlazeMapJoin<PolymorphicBase, String, PolymorphicSub1> treatedMapJoin = cb.treat(root.join(PolymorphicBase_.map, "map"), PolymorphicSub1.class); treatedJoin.on(treatedJoin.get(PolymorphicSub1_.sub1Value).isNotNull()).join(PolymorphicSub1_.relation1, "parentRelation1"); treatedJoin2.on(treatedJoin2.get(PolymorphicSub2_.sub2Value).isNotNull()).join(PolymorphicSub2_.relation2, "parent2Relation2"); treatedListJoin.on(treatedListJoin.get(PolymorphicSub1_.sub1Value).isNotNull()).join(PolymorphicSub1_.relation1, "listRelation1"); treatedSetJoin.on(treatedSetJoin.get(PolymorphicSub1_.sub1Value).isNotNull()).join(PolymorphicSub1_.relation1, "setRelation1"); treatedMapJoin.on(treatedMapJoin.get(PolymorphicSub1_.sub1Value).isNotNull()).join(PolymorphicSub1_.relation1, "mapRelation1"); cq.multiselect( treatedJoin.type(), treatedListJoin.type(), treatedSetJoin.type(), treatedMapJoin.type(), treatedMapJoin.key().type(), cb.treat(root.get(PolymorphicBase_.parent), PolymorphicSub1.class).type(), cb.treat(root.get(PolymorphicBase_.parent), PolymorphicSub1.class).get(PolymorphicSub1_.relation1).type() ); CriteriaBuilder<?> criteriaBuilder = cq.createCriteriaBuilder(); String whereFragment = null; whereFragment = treatJoinWhereFragment(PolymorphicBase.class, "children", "child", PolymorphicSub1.class, com.blazebit.persistence.JoinType.INNER, whereFragment); whereFragment = treatJoinWhereFragment(PolymorphicBase.class, "list", "list", PolymorphicSub1.class, com.blazebit.persistence.JoinType.INNER, whereFragment); whereFragment = treatJoinWhereFragment(PolymorphicBase.class, "map", "map", PolymorphicSub1.class, com.blazebit.persistence.JoinType.INNER, whereFragment); whereFragment = treatJoinWhereFragment(PolymorphicBase.class, "parent", "parent", PolymorphicSub1.class, com.blazebit.persistence.JoinType.INNER, whereFragment); whereFragment = treatJoinWhereFragment(PolymorphicBase.class, "parent2", "parent2", PolymorphicSub2.class, com.blazebit.persistence.JoinType.INNER, whereFragment); assertEquals("SELECT TYPE(parent), TYPE(list), TYPE(child), TYPE(map), TYPE(KEY(map)), TYPE(parent_1), TYPE(relation1_1) " + "FROM PolymorphicBase base" + " JOIN " + treatJoin("base.children", PolymorphicSub1.class) + " child" + onClause(treatJoinedConstraintFragment("child", PolymorphicSub1.class, ".sub1Value IS NOT NULL", false)) + " JOIN child.relation1 setRelation1" + " JOIN " + treatJoin("base.list", PolymorphicSub1.class) + " list" + onClause(treatJoinedConstraintFragment("list", PolymorphicSub1.class, ".sub1Value IS NOT NULL", false)) + " JOIN list.relation1 listRelation1" + " JOIN " + treatJoin("base.map", PolymorphicSub1.class) + " map" + onClause(treatJoinedConstraintFragment("map", PolymorphicSub1.class, ".sub1Value IS NOT NULL", false)) + " JOIN map.relation1 mapRelation1" + " JOIN " + treatJoin("base.parent", PolymorphicSub1.class) + " parent" + onClause(treatJoinedConstraintFragment("parent", PolymorphicSub1.class, ".sub1Value IS NOT NULL", false)) + " JOIN parent.relation1 parentRelation1" + " JOIN " + treatJoin("base.parent", PolymorphicSub2.class) + " parent2" + onClause(treatJoinedConstraintFragment("parent2", PolymorphicSub2.class, ".sub2Value IS NOT NULL", false)) + " JOIN parent2.relation2 parent2Relation2" + " LEFT JOIN base.parent parent_1" + " LEFT JOIN parent_1.relation1 relation1_1" + whereFragment, criteriaBuilder.getQueryString()); } @Test public void treatPath() { BlazeCriteriaQuery<Integer> cq = BlazeCriteria.get(em, cbf, Integer.class); BlazeCriteriaBuilder cb = cq.getCriteriaBuilder(); BlazeRoot<PolymorphicBase> root = cq.from(PolymorphicBase.class, "base"); cq.select(cb.treat(root.get(PolymorphicBase_.parent), PolymorphicSub1.class).get(PolymorphicSub1_.sub1Value)); cq.where(cb.treat(root.get(PolymorphicBase_.parent), PolymorphicSub1.class).get(PolymorphicSub1_.sub1Value).isNotNull()); CriteriaBuilder<?> criteriaBuilder = cq.createCriteriaBuilder(); String whereFragment = treatRootWhereFragment("parent_1", PolymorphicSub1.class, ".sub1Value IS NOT NULL", false); assertEquals("SELECT " + treatRoot("parent_1", PolymorphicSub1.class, "sub1Value") + " FROM PolymorphicBase base" + " LEFT JOIN base.parent parent_1" + " WHERE " + whereFragment, criteriaBuilder.getQueryString()); } }