Skip to content

Commit

Permalink
[Blazebit#708] Add test and support for nested join correlations
Browse files Browse the repository at this point in the history
  • Loading branch information
beikov committed Dec 19, 2018
1 parent 55341da commit 1322478
Show file tree
Hide file tree
Showing 7 changed files with 214 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public List<Object[]> transformAll(List<Object[]> tupleList) {
}

for (int i = 0; i < transformatorLevels.size(); i++) {
if (!transformatorLevels.get(i).tupleTransformers.isEmpty()) {
if (transformatorLevels.get(i).tupleTransformers.length != 0) {
ListIterator<Object[]> newTupleListIter = newTupleList.listIterator();

while (newTupleListIter.hasNext()) {
Expand Down Expand Up @@ -76,10 +76,10 @@ public List<Object[]> transformAll(List<Object[]> tupleList) {
}

private Object[] transform(int level, Object[] tuple, UpdatableViewMap updatableViewMap) {
List<TupleTransformer> tupleTransformers = transformatorLevels.get(level).tupleTransformers;
TupleTransformer[] tupleTransformers = transformatorLevels.get(level).tupleTransformers;
Object[] currentTuple = tuple;
for (int i = 0; i < tupleTransformers.size(); i++) {
currentTuple = tupleTransformers.get(i).transform(currentTuple, updatableViewMap);
for (int i = 0; i < tupleTransformers.length; i++) {
currentTuple = tupleTransformers[i].transform(currentTuple, updatableViewMap);
}
return currentTuple;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,8 @@ public void add(TupleTransformerFactory tupleTransformerFactory) {
public TupleTransformator create(ParameterHolder<?> parameterHolder, Map<String, Object> optionalParameters, EntityViewConfiguration entityViewConfiguration) {
List<TupleTransformatorLevel> newTransformatorLevels = new ArrayList<TupleTransformatorLevel>(transformatorLevels.size());
for (TupleTransformatorFactoryLevel thisLevel : transformatorLevels) {
final List<TupleTransformer> tupleTransformers = new ArrayList<TupleTransformer>(thisLevel.tupleTransformerFactories.size());
List<TupleTransformerFactory> tupleTransformerFactories = thisLevel.tupleTransformerFactories;
final TupleTransformer[] tupleTransformers = new TupleTransformer[tupleTransformerFactories.size()];
// No need to copy this, because TupleListTransformer are not context sensitive
final TupleListTransformer tupleListTransformer;

Expand All @@ -260,9 +261,11 @@ public TupleTransformator create(ParameterHolder<?> parameterHolder, Map<String,
} else {
tupleListTransformer = thisLevel.tupleListTransformer;
}

for (TupleTransformerFactory tupleTransformerFactory : thisLevel.tupleTransformerFactories) {
tupleTransformers.add(tupleTransformerFactory.create(parameterHolder, optionalParameters, entityViewConfiguration));

// We create the tuple transformers in the inverse order as deeper nested objects come first, yet we want to initialize stuff top-down to properly support nested join correlations
for (int i = tupleTransformerFactories.size() - 1; i >= 0; i--) {
TupleTransformerFactory tupleTransformerFactory = tupleTransformerFactories.get(i);
tupleTransformers[i] = tupleTransformerFactory.create(parameterHolder, optionalParameters, entityViewConfiguration);
}

newTransformatorLevels.add(new TupleTransformatorLevel(tupleTransformers, tupleListTransformer));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@

package com.blazebit.persistence.view.impl.objectbuilder.transformator;

import java.util.List;

import com.blazebit.persistence.view.impl.objectbuilder.transformer.TupleListTransformer;
import com.blazebit.persistence.view.impl.objectbuilder.transformer.TupleTransformer;

Expand All @@ -27,10 +25,10 @@
*/
class TupleTransformatorLevel {

final List<TupleTransformer> tupleTransformers;
final TupleTransformer[] tupleTransformers;
final TupleListTransformer tupleListTransformer;

public TupleTransformatorLevel(List<TupleTransformer> tupleTransformers,
public TupleTransformatorLevel(TupleTransformer[] tupleTransformers,
TupleListTransformer tupleListTransformer) {
this.tupleTransformers = tupleTransformers;
this.tupleListTransformer = tupleListTransformer;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
* Copyright 2014 - 2018 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.view.testsuite.correlation.nestedjoin;

import com.blazebit.persistence.CriteriaBuilder;
import com.blazebit.persistence.testsuite.base.jpa.category.NoDatanucleus;
import com.blazebit.persistence.testsuite.base.jpa.category.NoEclipselink;
import com.blazebit.persistence.testsuite.base.jpa.category.NoHibernate42;
import com.blazebit.persistence.testsuite.base.jpa.category.NoHibernate43;
import com.blazebit.persistence.testsuite.base.jpa.category.NoHibernate50;
import com.blazebit.persistence.testsuite.base.jpa.category.NoOpenJPA;
import com.blazebit.persistence.testsuite.entity.Document;
import com.blazebit.persistence.view.EntityViewManager;
import com.blazebit.persistence.view.EntityViewSetting;
import com.blazebit.persistence.view.EntityViews;
import com.blazebit.persistence.view.spi.EntityViewConfiguration;
import com.blazebit.persistence.view.testsuite.AbstractEntityViewTest;
import com.blazebit.persistence.view.testsuite.correlation.model.SimplePersonCorrelatedSubView;
import com.blazebit.persistence.view.testsuite.correlation.nestedjoin.model.DocumentNestedJoinView;
import com.blazebit.persistence.view.testsuite.correlation.nestedjoin.model.PersonNestedJoinSubView;
import com.blazebit.persistence.view.testsuite.correlation.nestedjoin.model.SimpleDocumentView;
import org.junit.Test;
import org.junit.experimental.categories.Category;

/**
*
* @author Christian Beikov
* @since 1.4.0
*/
public class JoinableCorrelationTest extends AbstractEntityViewTest {

// NOTE: Requires entity joins which are supported since Hibernate 5.1, Datanucleus 5 and latest Eclipselink
// NOTE: Eclipselink renders a cross join at the wrong position in the SQL
// NOTE: Eclipselink and Datanucleus don't support the single valued id access optimization which causes a cyclic join dependency
@Test
@Category({ NoHibernate42.class, NoHibernate43.class, NoHibernate50.class, NoDatanucleus.class, NoOpenJPA.class, NoEclipselink.class })
public void testNestedJoinCorrelation() {
EntityViewConfiguration cfg = EntityViews.createDefaultConfiguration();
cfg.addEntityView(DocumentNestedJoinView.class);
cfg.addEntityView(PersonNestedJoinSubView.class);
cfg.addEntityView(SimpleDocumentView.class);
EntityViewManager evm = cfg.createEntityViewManager(cbf);

CriteriaBuilder<Document> criteria = cbf.create(em, Document.class, "d");
EntityViewSetting<DocumentNestedJoinView, CriteriaBuilder<DocumentNestedJoinView>> setting =
EntityViewSetting.create(DocumentNestedJoinView.class);
CriteriaBuilder<DocumentNestedJoinView> cb = evm.applySetting(setting, criteria);
cb.getResultList();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* Copyright 2014 - 2018 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.view.testsuite.correlation.nestedjoin.model;

import com.blazebit.persistence.testsuite.entity.Document;
import com.blazebit.persistence.testsuite.entity.Person;
import com.blazebit.persistence.view.EntityView;
import com.blazebit.persistence.view.FetchStrategy;
import com.blazebit.persistence.view.IdMapping;
import com.blazebit.persistence.view.MappingCorrelatedSimple;

/**
*
* @author Christian Beikov
* @since 1.4.0
*/
@EntityView(Document.class)
public interface DocumentNestedJoinView {

@IdMapping
public Long getId();

@MappingCorrelatedSimple(
correlationBasis = "COALESCE(owner.id, 1)",
correlated = Person.class,
correlationExpression = "id IN correlationKey",
correlationResult = "friend",
fetch = FetchStrategy.JOIN
)
public PersonNestedJoinSubView getCorrelatedOwnerFriendView();

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
* Copyright 2014 - 2018 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.view.testsuite.correlation.nestedjoin.model;

import com.blazebit.persistence.testsuite.entity.Document;
import com.blazebit.persistence.testsuite.entity.Person;
import com.blazebit.persistence.view.AttributeFilter;
import com.blazebit.persistence.view.EntityView;
import com.blazebit.persistence.view.FetchStrategy;
import com.blazebit.persistence.view.IdMapping;
import com.blazebit.persistence.view.Mapping;
import com.blazebit.persistence.view.MappingCorrelatedSimple;
import com.blazebit.persistence.view.filter.ContainsFilter;

/**
*
* @author Christian Beikov
* @since 1.4.0
*/
@EntityView(Person.class)
public interface PersonNestedJoinSubView {

@IdMapping
public Long getId();

@Mapping("UPPER(name)")
@AttributeFilter(ContainsFilter.class)
public String getName();

@MappingCorrelatedSimple(
correlationBasis = "COALESCE(partnerDocument.id, 1)",
correlated = Document.class,
correlationExpression = "id IN correlationKey",
fetch = FetchStrategy.JOIN
)
public SimpleDocumentView getPartnerDocument();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* Copyright 2014 - 2018 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.view.testsuite.correlation.nestedjoin.model;

import com.blazebit.persistence.testsuite.entity.Document;
import com.blazebit.persistence.view.EntityView;
import com.blazebit.persistence.view.IdMapping;
import com.blazebit.persistence.view.testsuite.correlation.model.SimplePersonCorrelatedSubView;

import java.util.Set;

/**
*
* @author Christian Beikov
* @since 1.4.0
*/
@EntityView(Document.class)
public interface SimpleDocumentView {

@IdMapping
public Long getId();

public String getName();

}

0 comments on commit 1322478

Please sign in to comment.