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 String[] columns;
|
||||
|
||||
public String[] getColumns() {
|
||||
return columns;
|
||||
}
|
||||
|
||||
public void resolveIndex(AST parent) throws SemanticException {
|
||||
// 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.
|
||||
}
|
||||
|
||||
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) {
|
||||
if (!isResolved()) {
|
||||
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();
|
||||
// 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) {
|
||||
DotNode dot = (DotNode) parent;
|
||||
if (parent.getFirstChild() == this) {
|
||||
|
@ -338,8 +387,13 @@ public class IdentNode extends FromReferenceNode implements SelectExpression {
|
|||
else {
|
||||
FromElement fe = getFromElement();
|
||||
if (fe != null) {
|
||||
if ( fe.getQueryableCollection() != null && fe.getQueryableCollection().getElementType().isComponentType() ) {
|
||||
ColumnHelper.generateScalarColumns( this, getColumns(), i );
|
||||
}
|
||||
else {
|
||||
setText(fe.renderScalarIdentifierSelect(i));
|
||||
}
|
||||
}
|
||||
else {
|
||||
ColumnHelper.generateSingleScalarColumn(this, i);
|
||||
}
|
||||
|
|
|
@ -14,7 +14,6 @@ import javax.persistence.Column;
|
|||
import javax.persistence.ElementCollection;
|
||||
import javax.persistence.Embeddable;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.EnumType;
|
||||
import javax.persistence.Enumerated;
|
||||
import javax.persistence.GeneratedValue;
|
||||
|
@ -33,10 +32,12 @@ import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
|
|||
import org.hibernate.testing.TestForIssue;
|
||||
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
|
||||
protected Class<?>[] getAnnotatedClasses() {
|
||||
return new Class[] {Batch.class, Node.class, BatchNodeMetadata.class};
|
||||
|
@ -45,9 +46,8 @@ public class MapJoinTest2 extends BaseEntityManagerFunctionalTestCase {
|
|||
@Test
|
||||
@TestForIssue( jiraKey = "HHH-10455" )
|
||||
public void testSelectingKeyOfMapJoin() {
|
||||
EntityManager em = getOrCreateEntityManager();
|
||||
|
||||
CriteriaBuilder cb = em.getCriteriaBuilder();
|
||||
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
|
||||
CriteriaQuery<Node> query = cb.createQuery( Node.class );
|
||||
Root<Batch> root = query.from( Batch.class );
|
||||
|
||||
|
@ -56,9 +56,25 @@ public class MapJoinTest2 extends BaseEntityManagerFunctionalTestCase {
|
|||
query.select( nodes.key() );
|
||||
query.where( cb.equal( root.get( "id" ), 1 ) );
|
||||
|
||||
em.createQuery( query ).getResultList();
|
||||
entityManager.createQuery( query ).getResultList();
|
||||
} );
|
||||
}
|
||||
|
||||
em.close();
|
||||
@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 );
|
||||
|
||||
MapJoin nodes = (MapJoin) root.join( "batchNodeMetadata" );
|
||||
|
||||
query.select( nodes );
|
||||
query.where( cb.equal( root.get( "id" ), 1 ) );
|
||||
|
||||
entityManager.createQuery( query ).getResultList();
|
||||
} );
|
||||
}
|
||||
|
||||
@Entity
|
Loading…
Reference in New Issue