Skip to content

Commit

Permalink
[#1294] Fix various issues with type resolving paths that match entit…
Browse files Browse the repository at this point in the history
…y names
  • Loading branch information
beikov committed Apr 23, 2021
1 parent 176f62d commit 1006d3b
Show file tree
Hide file tree
Showing 7 changed files with 158 additions and 7 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ None yet
* Workaround Hibernate proxy field access bug for non-pk relations
* Fix issues with de-serializing of singular entity view attributes that use a collection type
* Add Cockroach DBMS detection and a `DbmsDialect` implementation
* Fix various issues with type resolving paths that match entity names

### Backwards-incompatible changes

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2866,7 +2866,7 @@ public void implicitJoin(Expression expression, boolean joinAllowed, boolean sin
Type<?> type = attributeHolder.getAttributeType();
result = new JoinResult(currentResult.baseNode, Arrays.asList(elementString), type, -1, -1);
} else if (metamodel.getManagedType(ExtendedManagedType.class, current.getManagedType()).getAttributes().get(associationName) != null) {
Expression resultExpr = expressionFactory.createSimpleExpression(associationName, false);
Expression resultExpr = new PathExpression(new PropertyExpression(associationName));
AttributeHolder attributeHolder = JpaUtils.getAttributeForJoining(
metamodel,
current.getNodeType(),
Expand Down Expand Up @@ -3475,13 +3475,11 @@ private JoinResult implicitJoin(JoinNode current, List<String> resultFields, Pat
if (resultFields.isEmpty()) {
return new JoinResult(current, null, current == null ? null : current.getNodeType(), singleValuedAssociationNameStartIndex, singleValuedAssociationNameEndIndex);
} else {
StringBuilder sb = new StringBuilder();
sb.append(resultFields.get(0));
for (int i = 1; i < resultFields.size(); i++) {
sb.append('.');
sb.append(resultFields.get(i));
List<PathElementExpression> pathElementExpressions = new ArrayList<>(resultFields.size());
for (int i = 0; i < resultFields.size(); i++) {
pathElementExpressions.add(new PropertyExpression(resultFields.get(i)));
}
Expression expression = expressionFactory.createSimpleExpression(sb.toString(), false);
Expression expression = new PathExpression(pathElementExpressions);
Type<?> type = JpaUtils.getAttributeForJoining(metamodel, current.getNodeType(), expression, null).getAttributeType();
return new JoinResult(current, resultFields, type, singleValuedAssociationNameStartIndex, singleValuedAssociationNameEndIndex);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,14 @@ public Expression createPathExpression(String expression, MacroConfiguration mac
List<PathElementExpression> pathElements = new ArrayList<>(1);
pathElements.add((PathElementExpression) expr);
return new PathExpression(pathElements);
} else if (expr instanceof EntityLiteral) {
// Special case where the path matches an entity name
String[] parts = ((EntityLiteral) expr).getOriginalExpression().split("\\.");
List<PathElementExpression> pathElements = new ArrayList<>(parts.length);
for (String part : parts) {
pathElements.add(new PropertyExpression(part));
}
return new PathExpression(pathElements);
} else if (expr instanceof FunctionExpression) {
return expr;
} else {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
* Copyright 2014 - 2021 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.testsuite.entity;

import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
import java.io.Serializable;

/**
*
* @author Christian Beikov
* @since 1.6.0
*/
@Entity
public class DocumentHolder implements Serializable {
private static final long serialVersionUID = 1L;

@Id
private Long id;
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "document_id")
// CHECKSTYLE:OFF: MemberName
private Document Document;
// CHECKSTYLE:ON: MemberName

public DocumentHolder() {
}

public Long getId() {
return id;
}

public void setId(Long id) {
this.id = id;
}

public Document getDocument() {
return Document;
}

public void setDocument(Document document) {
this.Document = document;
}

}
1 change: 1 addition & 0 deletions core/testsuite/src/main/resources/META-INF/persistence.xml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
<class>com.blazebit.persistence.testsuite.entity.DocumentForOneToOneJoinTable</class>
<class>com.blazebit.persistence.testsuite.entity.DocumentForOneToOne</class>
<class>com.blazebit.persistence.testsuite.entity.DocumentForSimpleOneToOne</class>
<class>com.blazebit.persistence.testsuite.entity.DocumentHolder</class>
<class>com.blazebit.persistence.testsuite.entity.DocumentInfo</class>
<class>com.blazebit.persistence.testsuite.entity.DocumentInfoSimple</class>
<class>com.blazebit.persistence.testsuite.entity.DocumentNodeCTE</class>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import com.blazebit.persistence.parser.AliasReplacementVisitor;
import com.blazebit.persistence.parser.EntityMetamodel;
import com.blazebit.persistence.parser.expression.AbstractCachingExpressionFactory;
import com.blazebit.persistence.parser.expression.EntityLiteral;
import com.blazebit.persistence.parser.expression.Expression;
import com.blazebit.persistence.parser.expression.ExpressionFactory;
import com.blazebit.persistence.parser.expression.MacroConfiguration;
Expand Down Expand Up @@ -54,6 +55,7 @@
import com.blazebit.persistence.view.spi.type.TypeConverter;
import com.blazebit.reflection.ReflectionUtils;

import javax.persistence.metamodel.Attribute;
import javax.persistence.metamodel.ManagedType;
import java.lang.annotation.Annotation;
import java.util.ArrayList;
Expand Down Expand Up @@ -346,6 +348,15 @@ public List<ScalarTargetResolvingExpressionVisitor.TargetType> getPossibleTarget
));
}
Expression simpleExpression = typeValidationExpressionFactory.createSimpleExpression(expression, false, false, true);
if (simpleExpression instanceof EntityLiteral) {
// This is a special case where the mapping i.e. attribute name matches an entity name
try {
Attribute<?, ?> attribute = managedType.getAttribute(expression);
return Collections.<ScalarTargetResolvingExpressionVisitor.TargetType>singletonList(new ScalarTargetResolvingExpressionVisitor.TargetTypeImpl(false, attribute, attribute.getJavaType(), null, attribute.getJavaType()));
} catch (IllegalArgumentException ex) {
// Apparently it's not an attribute, so let it run through
}
}
ScalarTargetResolvingExpressionVisitor visitor = new ScalarTargetResolvingExpressionVisitor(managedType, entityMetamodel, jpqlFunctions, rootTypes);
simpleExpression.accept(visitor);
return visitor.getPossibleTargetTypes();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/*
* Copyright 2014 - 2021 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.basic;

import com.blazebit.persistence.testsuite.entity.Document;
import com.blazebit.persistence.testsuite.entity.DocumentHolder;
import com.blazebit.persistence.view.EntityView;
import com.blazebit.persistence.view.EntityViewManager;
import com.blazebit.persistence.view.IdMapping;
import com.blazebit.persistence.view.Mapping;
import com.blazebit.persistence.view.testsuite.AbstractEntityViewTest;
import org.junit.Before;
import org.junit.Test;

/**
*
* @author Christian Beikov
* @since 1.6.0
*/
public class AttributeMatchesEntityNameTest extends AbstractEntityViewTest {

protected EntityViewManager evm;

@Override
protected Class<?>[] getEntityClasses() {
return concat(super.getEntityClasses(), DocumentHolder.class);
}

@Before
public void initEvm() {
evm = build(
DocumentHolderView.class,
DocumentIdView.class
);
}

@EntityView(DocumentHolder.class)
public interface DocumentHolderView {
@IdMapping
Long getId();
@Mapping("Document")
DocumentIdView getDocument();
}

@EntityView(Document.class)
public interface DocumentIdView {
@IdMapping
Long getId();
}

// Test for https://github.com/Blazebit/blaze-persistence/issues/1294
@Test
public void testFetch() {
evm.find(em, DocumentHolderView.class, 1L);
}
}

0 comments on commit 1006d3b

Please sign in to comment.