Skip to content

Commit b8361df

Browse files
committed
Fix for issue 2211
1 parent 23a88d5 commit b8361df

File tree

2 files changed

+66
-23
lines changed

2 files changed

+66
-23
lines changed

foundation/org.eclipse.persistence.core/src/main/java/org/eclipse/persistence/internal/jpa/jpql/JPQLFunctionsAbstractBuilder.java

+64-22
Original file line numberDiff line numberDiff line change
@@ -28,18 +28,23 @@
2828
import java.util.List;
2929

3030
/**
31-
* JPQL exclusive ID(), VERSION() functions/expressions are transformed there to StateFieldPathExpression.
32-
* It should be used in the future for another JPQL functions/expressions which are not available at the DB level.
33-
* E.g. For Entity e with idAttr as a primary key: <code>SELECT ID(e) FROM Entity e -> SELECT e.idAttr FROM Entity e</code>
34-
* For Entity e with versionAttr as a version attribute: <code>SELECT VERSION(e) FROM Entity e -> SELECT e.versionAttr FROM Entity e</code>
31+
* JPQL exclusive ID(), VERSION() functions/expressions are transformed there to
32+
* StateFieldPathExpression.
33+
* It should be used in the future for another JPQL functions/expressions which
34+
* are not available at the DB level.
35+
* E.g. For Entity e with idAttr as a primary key:
36+
* <code>SELECT ID(e) FROM Entity e -> SELECT e.idAttr FROM Entity e</code>
37+
* For Entity e with versionAttr as a version attribute:
38+
* <code>SELECT VERSION(e) FROM Entity e -> SELECT e.versionAttr FROM Entity e</code>
3539
*
3640
* @author Radek Felcman
3741
* @since 5.0
3842
*/
3943
public abstract class JPQLFunctionsAbstractBuilder extends EclipseLinkAnonymousExpressionVisitor {
4044

4145
/**
42-
* The {@link JPQLQueryContext} is used to query information about the application metadata and
46+
* The {@link JPQLQueryContext} is used to query information about the
47+
* application metadata and
4348
* cached information.
4449
*/
4550
final JPQLQueryContext queryContext;
@@ -49,57 +54,94 @@ protected JPQLFunctionsAbstractBuilder(JPQLQueryContext queryContext) {
4954
}
5055

5156
/**
52-
* For Entity e with idAttr as a primary key: <code>SELECT ID(e) FROM Entity e -> SELECT e.idAttr FROM Entity e</code>
57+
* For Entity e with idAttr as a primary key:
58+
* <code>SELECT ID(e) FROM Entity e -> SELECT e.idAttr FROM Entity e</code>
5359
*
5460
* @param expression The {@link IdExpression} to visit
5561
*/
5662
@Override
5763
public void visit(IdExpression expression) {
58-
//Fetch identification variable info
64+
System.out.println("INSIDE VISIT *******");
5965
IdentificationVariable identificationVariable = (IdentificationVariable) expression.getExpression();
6066
String variableText = identificationVariable.getText();
6167
String variableName = identificationVariable.getVariableName();
62-
63-
//Get id attribute name
68+
// Get id attribute name
6469
ClassDescriptor descriptor = this.queryContext.getDeclaration(variableName).getDescriptor();
6570
List<DatabaseField> primaryKeyFields = descriptor.getPrimaryKeyFields();
66-
String idAttributeName = getIdAttributeNameByField(descriptor.getMappings(), primaryKeyFields.get(0));
67-
StateFieldPathExpression stateFieldPathExpression = new StateFieldPathExpression(expression.getParent(), variableText + "." + idAttributeName);
68-
expression.setStateFieldPathExpression(stateFieldPathExpression);
71+
// String idAttributeName = getIdAttributeNameByField(descriptor.getMappings(),
72+
// primaryKeyFields.get(0));
73+
// StateFieldPathExpression stateFieldPathExpression = new
74+
// StateFieldPathExpression(expression.getParent(), variableText + "." +
75+
// idAttributeName);
76+
// expression.setStateFieldPathExpression(stateFieldPathExpression);
77+
// expression.getStateFieldPathExpression().accept(this);
78+
if (!isEmbeddable(descriptor.getMappings())) {
79+
for (DatabaseField primaryKeyField : primaryKeyFields) {
80+
String idAttributeName = getIdAttributeNameByField(descriptor.getMappings(), primaryKeyField);
81+
StateFieldPathExpression stateFieldPathExpression = new StateFieldPathExpression(
82+
expression.getParent(), variableText + "." + idAttributeName);
83+
expression.setStateFieldPathExpression(stateFieldPathExpression);
84+
// Continue with created StateFieldPathExpression
85+
// It handle by ObjectBuilder booth @Id/primary key types (simple/composite)
86+
expression.getStateFieldPathExpression().accept(this);
87+
}
88+
} else {
89+
String idAttributeName = getIdAttributeNameByField(descriptor.getMappings(), primaryKeyFields.get(0));
90+
StateFieldPathExpression stateFieldPathExpression = new StateFieldPathExpression(
91+
expression.getParent(), variableText + "." + idAttributeName);
92+
expression.setStateFieldPathExpression(stateFieldPathExpression);
93+
// Continue with created StateFieldPathExpression
94+
// It handle by ObjectBuilder booth @Id/primary key types (simple/composite)
95+
expression.getStateFieldPathExpression().accept(this);
6996

70-
//Continue with created StateFieldPathExpression
71-
//It handle by ObjectBuilder booth @Id/primary key types (simple/composite)
72-
expression.getStateFieldPathExpression().accept(this);
97+
}
7398
}
7499

75100
/**
76-
* For Entity e with versionAttr as a version attribute: <code>SELECT VERSION(e) FROM Entity e -> SELECT e.versionAttr FROM Entity e</code>
101+
* For Entity e with versionAttr as a version attribute:
102+
* <code>SELECT VERSION(e) FROM Entity e -> SELECT e.versionAttr FROM Entity e</code>
77103
*
78104
* @param expression The {@link VersionExpression} to visit
79105
*/
80106
@Override
81107
public void visit(VersionExpression expression) {
82-
//Fetch identification variable info
108+
// Fetch identification variable info
83109
IdentificationVariable identificationVariable = (IdentificationVariable) expression.getExpression();
84110
String variableText = identificationVariable.getText();
85111
String variableName = identificationVariable.getVariableName();
86112

87-
//Get version attribute name
113+
// Get version attribute name
88114
ClassDescriptor descriptor = this.queryContext.getDeclaration(variableName).getDescriptor();
89-
String versionAttributeName = ((VersionLockingPolicy) descriptor.getOptimisticLockingPolicy()).getVersionMapping().getAttributeName();
90-
StateFieldPathExpression stateFieldPathExpression = new StateFieldPathExpression(expression.getParent(), variableText + "." + versionAttributeName);
115+
String versionAttributeName = ((VersionLockingPolicy) descriptor.getOptimisticLockingPolicy())
116+
.getVersionMapping().getAttributeName();
117+
StateFieldPathExpression stateFieldPathExpression = new StateFieldPathExpression(expression.getParent(),
118+
variableText + "." + versionAttributeName);
91119
expression.setStateFieldPathExpression(stateFieldPathExpression);
92120

93-
//Continue with created StateFieldPathExpression
121+
// Continue with created StateFieldPathExpression
94122
expression.getStateFieldPathExpression().accept(this);
95123
}
96124

97125
private String getIdAttributeNameByField(List<DatabaseMapping> databaseMappings, DatabaseField field) {
98126
for (DatabaseMapping mapping : databaseMappings) {
99-
if (field.equals(mapping.getField()) || mapping.isPrimaryKeyMapping()) {
127+
if (mapping.getFields().size() > 1 && (field.equals(mapping.getField()) || mapping.isPrimaryKeyMapping())) {
100128
return mapping.getAttributeName();
129+
} else {
130+
if ((field.equals(mapping.getField()) && mapping.isPrimaryKeyMapping())) {
131+
return mapping.getAttributeName();
132+
}
101133
}
102134
}
103135
return null;
104136
}
137+
138+
private boolean isEmbeddable(List<DatabaseMapping> databaseMappings) {
139+
140+
for (DatabaseMapping databaseMapping : databaseMappings) {
141+
if (databaseMapping.isPrimaryKeyMapping() && databaseMapping.getFields().size() > 1) {
142+
return true;
143+
}
144+
}
145+
return false;
146+
}
105147
}

foundation/org.eclipse.persistence.core/src/main/java/org/eclipse/persistence/internal/jpa/jpql/ReportItemBuilder.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
import org.eclipse.persistence.jpa.jpql.parser.EntryExpression;
4242
import org.eclipse.persistence.jpa.jpql.parser.ExtractExpression;
4343
import org.eclipse.persistence.jpa.jpql.parser.FunctionExpression;
44+
import org.eclipse.persistence.jpa.jpql.parser.IdExpression;
4445
import org.eclipse.persistence.jpa.jpql.parser.IdentificationVariable;
4546
import org.eclipse.persistence.jpa.jpql.parser.IndexExpression;
4647
import org.eclipse.persistence.jpa.jpql.parser.Join;
@@ -630,7 +631,7 @@ private void visitAbstractSelectClause(AbstractSelectClause expression) {
630631
multipleSelects = false;
631632
expression.getSelectExpression().accept(this);
632633

633-
if (multipleSelects) {
634+
if (multipleSelects || (expression.getSelectExpression() instanceof IdExpression)) {
634635
query.returnWithoutReportQueryResult();
635636
}
636637
else {

0 commit comments

Comments
 (0)