HHH-10229 - Select value from element collection results in wrong SQL being produced
This commit is contained in:
parent
9aa164ed27
commit
d48ac0f0f7
|
@ -39,6 +39,11 @@ public class IdentNode extends FromReferenceNode implements SelectExpression {
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean nakedPropertyRef;
|
private boolean nakedPropertyRef;
|
||||||
|
private String[] columns;
|
||||||
|
|
||||||
|
public String[] getColumns() {
|
||||||
|
return columns;
|
||||||
|
}
|
||||||
|
|
||||||
public void resolveIndex(AST parent) throws SemanticException {
|
public void resolveIndex(AST parent) throws SemanticException {
|
||||||
// An ident node can represent an index expression if the ident
|
// An ident node can represent an index expression if the ident
|
||||||
|
@ -80,14 +85,58 @@ public class IdentNode extends FromReferenceNode implements SelectExpression {
|
||||||
getWalker().addQuerySpaces(queryableCollection.getCollectionSpaces()); // Always add the collection's query spaces.
|
getWalker().addQuerySpaces(queryableCollection.getCollectionSpaces()); // Always add the collection's query spaces.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected String[] resolveColumns(QueryableCollection collectionPersister) {
|
||||||
|
final FromElement fromElement = getFromElement();
|
||||||
|
return fromElement.toColumns(
|
||||||
|
fromElement.getCollectionTableAlias(),
|
||||||
|
"elements", // the JPA VALUE "qualifier" is the same concept as the HQL ELEMENTS function/property
|
||||||
|
getWalker().isInSelect()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initText(String[] columns) {
|
||||||
|
String text = StringHelper.join( ", ", columns );
|
||||||
|
if ( columns.length > 1 && getWalker().isComparativeExpressionClause() ) {
|
||||||
|
text = "(" + text + ")";
|
||||||
|
}
|
||||||
|
setText( text );
|
||||||
|
}
|
||||||
|
|
||||||
public void resolve(boolean generateJoin, boolean implicitJoin, String classAlias, AST parent) {
|
public void resolve(boolean generateJoin, boolean implicitJoin, String classAlias, AST parent) {
|
||||||
if (!isResolved()) {
|
if (!isResolved()) {
|
||||||
if (getWalker().getCurrentFromClause().isFromElementAlias(getText())) {
|
if ( getWalker().getCurrentFromClause().isFromElementAlias( getText() ) ) {
|
||||||
if (resolveAsAlias()) {
|
FromElement fromElement = getWalker().getCurrentFromClause().getFromElement( getText() );
|
||||||
|
if ( fromElement.getQueryableCollection() != null && fromElement.getQueryableCollection().getElementType().isComponentType() ) {
|
||||||
|
if ( getWalker().isInSelect() ) {
|
||||||
|
// This is a reference to an element collection
|
||||||
|
setFromElement( fromElement );
|
||||||
|
super.setDataType( fromElement.getQueryableCollection().getElementType() );
|
||||||
|
this.columns = resolveColumns( fromElement.getQueryableCollection() );
|
||||||
|
initText( getColumns() );
|
||||||
|
setFirstChild( null );
|
||||||
|
// Don't resolve it
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
resolveAsAlias();
|
||||||
|
// Don't resolve it
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ( resolveAsAlias() ) {
|
||||||
setResolved();
|
setResolved();
|
||||||
// We represent a from-clause alias
|
// We represent a from-clause alias
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (
|
||||||
|
getColumns() != null
|
||||||
|
&& ( getWalker().getAST() instanceof AbstractMapComponentNode || getWalker().getAST() instanceof IndexNode )
|
||||||
|
&& getWalker().getCurrentFromClause().isFromElementAlias( getOriginalText() )
|
||||||
|
) {
|
||||||
|
// We might have to revert our decision that this is naked element collection reference when we encounter it is embedded in a map function
|
||||||
|
setText( getOriginalText() );
|
||||||
|
if ( resolveAsAlias() ) {
|
||||||
|
setResolved();
|
||||||
|
}
|
||||||
|
}
|
||||||
else if (parent != null && parent.getType() == SqlTokenTypes.DOT) {
|
else if (parent != null && parent.getType() == SqlTokenTypes.DOT) {
|
||||||
DotNode dot = (DotNode) parent;
|
DotNode dot = (DotNode) parent;
|
||||||
if (parent.getFirstChild() == this) {
|
if (parent.getFirstChild() == this) {
|
||||||
|
@ -338,7 +387,12 @@ public class IdentNode extends FromReferenceNode implements SelectExpression {
|
||||||
else {
|
else {
|
||||||
FromElement fe = getFromElement();
|
FromElement fe = getFromElement();
|
||||||
if (fe != null) {
|
if (fe != null) {
|
||||||
setText(fe.renderScalarIdentifierSelect(i));
|
if ( fe.getQueryableCollection() != null && fe.getQueryableCollection().getElementType().isComponentType() ) {
|
||||||
|
ColumnHelper.generateScalarColumns( this, getColumns(), i );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
setText(fe.renderScalarIdentifierSelect(i));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ColumnHelper.generateSingleScalarColumn(this, i);
|
ColumnHelper.generateSingleScalarColumn(this, i);
|
||||||
|
|
|
@ -14,7 +14,6 @@ import javax.persistence.Column;
|
||||||
import javax.persistence.ElementCollection;
|
import javax.persistence.ElementCollection;
|
||||||
import javax.persistence.Embeddable;
|
import javax.persistence.Embeddable;
|
||||||
import javax.persistence.Entity;
|
import javax.persistence.Entity;
|
||||||
import javax.persistence.EntityManager;
|
|
||||||
import javax.persistence.EnumType;
|
import javax.persistence.EnumType;
|
||||||
import javax.persistence.Enumerated;
|
import javax.persistence.Enumerated;
|
||||||
import javax.persistence.GeneratedValue;
|
import javax.persistence.GeneratedValue;
|
||||||
|
@ -33,10 +32,12 @@ import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
|
||||||
import org.hibernate.testing.TestForIssue;
|
import org.hibernate.testing.TestForIssue;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import static org.hibernate.testing.transaction.TransactionUtil.doInJPA;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Steve Ebersole
|
* @author Christian Beikov
|
||||||
*/
|
*/
|
||||||
public class MapJoinTest2 extends BaseEntityManagerFunctionalTestCase {
|
public class MapJoinTestWithEmbeddable extends BaseEntityManagerFunctionalTestCase {
|
||||||
@Override
|
@Override
|
||||||
protected Class<?>[] getAnnotatedClasses() {
|
protected Class<?>[] getAnnotatedClasses() {
|
||||||
return new Class[] {Batch.class, Node.class, BatchNodeMetadata.class};
|
return new Class[] {Batch.class, Node.class, BatchNodeMetadata.class};
|
||||||
|
@ -45,20 +46,35 @@ public class MapJoinTest2 extends BaseEntityManagerFunctionalTestCase {
|
||||||
@Test
|
@Test
|
||||||
@TestForIssue( jiraKey = "HHH-10455" )
|
@TestForIssue( jiraKey = "HHH-10455" )
|
||||||
public void testSelectingKeyOfMapJoin() {
|
public void testSelectingKeyOfMapJoin() {
|
||||||
EntityManager em = getOrCreateEntityManager();
|
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||||
|
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
|
||||||
|
CriteriaQuery<Node> query = cb.createQuery( Node.class );
|
||||||
|
Root<Batch> root = query.from( Batch.class );
|
||||||
|
|
||||||
CriteriaBuilder cb = em.getCriteriaBuilder();
|
MapJoin nodes = (MapJoin) root.join( "batchNodeMetadata" );
|
||||||
CriteriaQuery<Node> query = cb.createQuery( Node.class );
|
|
||||||
Root<Batch> root = query.from( Batch.class );
|
|
||||||
|
|
||||||
MapJoin nodes = (MapJoin) root.join( "batchNodeMetadata" );
|
query.select( nodes.key() );
|
||||||
|
query.where( cb.equal( root.get( "id" ), 1 ) );
|
||||||
|
|
||||||
query.select( nodes.key() );
|
entityManager.createQuery( query ).getResultList();
|
||||||
query.where( cb.equal( root.get( "id" ), 1 ) );
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
em.createQuery( query ).getResultList();
|
@Test
|
||||||
|
@TestForIssue( jiraKey = "HHH-10229" )
|
||||||
|
public void testSelectingValueOfMapJoin() {
|
||||||
|
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||||
|
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
|
||||||
|
CriteriaQuery<Node> query = cb.createQuery( Node.class );
|
||||||
|
Root<Batch> root = query.from( Batch.class );
|
||||||
|
|
||||||
em.close();
|
MapJoin nodes = (MapJoin) root.join( "batchNodeMetadata" );
|
||||||
|
|
||||||
|
query.select( nodes );
|
||||||
|
query.where( cb.equal( root.get( "id" ), 1 ) );
|
||||||
|
|
||||||
|
entityManager.createQuery( query ).getResultList();
|
||||||
|
} );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Entity
|
@Entity
|
Loading…
Reference in New Issue