Skip to content

Commit a05387e

Browse files
committed
[#1832] Fix over-fetching of entity view data with dynamic fetches
1 parent eba3e5a commit a05387e

File tree

3 files changed

+57
-5
lines changed

3 files changed

+57
-5
lines changed

CHANGELOG.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ None yet
1010

1111
### Bug fixes
1212

13-
None yet
13+
* Fix over-fetching of entity view data with dynamic fetches
1414

1515
### Backwards-incompatible changes
1616

entity-view/impl/src/main/java/com/blazebit/persistence/view/impl/objectbuilder/ViewTypeObjectBuilder.java

+7-4
Original file line numberDiff line numberDiff line change
@@ -101,15 +101,15 @@ public <X extends SelectBuilder<X>> void applySelects(X queryBuilder) {
101101
if (secondaryMappers.length != 0) {
102102
FullQueryBuilder<?, ?> fullQueryBuilder = (FullQueryBuilder<?, ?>) queryBuilder;
103103
for (SecondaryMapper viewRoot : secondaryMappers) {
104-
if (hasSubFetches(viewRoot.getAttributePath())) {
104+
if (hasSubFetches(fetches, viewRoot.getAttributePath())) {
105105
viewRoot.apply(fullQueryBuilder, parameterHolder, optionalParameters, viewJpqlMacro, embeddingViewJpqlMacro);
106106
}
107107
}
108108
}
109109
for (int i = 0; i < mappers.length; i++) {
110110
TupleElementMapper mapper = mappers[i];
111111
String attributePath = mapper.getAttributePath();
112-
if (attributePath != null && hasSubFetches(attributePath)) {
112+
if (attributePath != null && hasSubFetches(fetches, attributePath)) {
113113
mapper.applyMapping(queryBuilder, parameterHolder, optionalParameters, viewJpqlMacro, embeddingViewJpqlMacro, false);
114114
} else {
115115
queryBuilder.select("NULL");
@@ -118,8 +118,11 @@ public <X extends SelectBuilder<X>> void applySelects(X queryBuilder) {
118118
}
119119
}
120120

121-
private boolean hasSubFetches(String attributePath) {
121+
static boolean hasSubFetches(NavigableSet<String> fetches, String attributePath) {
122+
// Fetches can never contain a path leading to a view i.e. one for which a dot is allowed to follow.
123+
// To find a potential match in the fetches, we have to look for an entry that is greater-or-equal to a path
124+
// See EntityViewConfiguration.getFetches(Collection, ManagedViewTypeImplementor)
122125
String fetchedPath = fetches.ceiling(attributePath);
123-
return fetchedPath != null && (fetchedPath.length() == attributePath.length() || fetchedPath.startsWith(attributePath) && fetchedPath.length() > attributePath.length() && fetchedPath.charAt(attributePath.length()) == '.');
126+
return fetchedPath != null && fetchedPath.startsWith(attributePath) && (fetchedPath.length() == attributePath.length() || fetchedPath.charAt(attributePath.length()) == '.');
124127
}
125128
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/*
2+
* Copyright 2014 - 2023 Blazebit.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.blazebit.persistence.view.impl.objectbuilder;
17+
18+
import java.util.TreeSet;
19+
20+
import org.junit.Test;
21+
22+
import static org.junit.Assert.assertFalse;
23+
import static org.junit.Assert.assertTrue;
24+
25+
/**
26+
*
27+
* @author Christian Beikov
28+
* @since 1.6.11
29+
*/
30+
public class ViewTypeObjectBuilderTest {
31+
32+
// Test for #1832
33+
@Test
34+
public void hasSubFetches() {
35+
TreeSet<String> fetches = new TreeSet<>();
36+
fetches.add( "id" );
37+
fetches.add( "bbbbbb" );
38+
fetches.add( "a.name" );
39+
assertTrue(ViewTypeObjectBuilder.hasSubFetches(fetches, "id"));
40+
assertTrue(ViewTypeObjectBuilder.hasSubFetches(fetches, "bbbbbb"));
41+
assertFalse(ViewTypeObjectBuilder.hasSubFetches(fetches, "aaa.id"));
42+
assertFalse(ViewTypeObjectBuilder.hasSubFetches(fetches, "ccc.id"));
43+
assertFalse(ViewTypeObjectBuilder.hasSubFetches(fetches, "bbbbb"));
44+
assertFalse(ViewTypeObjectBuilder.hasSubFetches(fetches, "bbbbbbb"));
45+
assertTrue(ViewTypeObjectBuilder.hasSubFetches(fetches, "a"));
46+
assertTrue(ViewTypeObjectBuilder.hasSubFetches(fetches, "a.name"));
47+
assertFalse(ViewTypeObjectBuilder.hasSubFetches(fetches, "a.id"));
48+
}
49+
}

0 commit comments

Comments
 (0)