Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -339,12 +339,18 @@ public String[] getIdentityColumns() {
throw new IllegalStateException( "No table alias for node " + this );
}

final String propertyName = getIdentifierPropertyName();

return toColumns(
table, propertyName,
getWalker().getStatementType() == HqlSqlTokenTypes.SELECT
);
final String[] propertyNames = getIdentifierPropertyNames();
List<String> columns = new ArrayList<>();
for ( int i = 0; i < propertyNames.length; i++ ) {
String[] propertyNameColumns = toColumns(
table, propertyNames[i],
getWalker().getStatementType() == HqlSqlTokenTypes.SELECT
);
for ( int j = 0; j < propertyNameColumns.length; j++ ) {
columns.add( propertyNameColumns[j] );
}
}
return columns.toArray( new String[columns.size()] );
}

public void setCollectionJoin(boolean collectionJoin) {
Expand Down Expand Up @@ -525,8 +531,8 @@ public CollectionPropertyReference getCollectionPropertyReference(String propert
return elementType.getCollectionPropertyReference( propertyName );
}

public String getIdentifierPropertyName() {
return elementType.getIdentifierPropertyName();
public String[] getIdentifierPropertyNames() {
return elementType.getIdentifierPropertyNames();
}

public void setFetch(boolean fetch) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,14 @@
import org.hibernate.MappingException;
import org.hibernate.QueryException;
import org.hibernate.engine.internal.JoinSequence;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.hql.internal.CollectionProperties;
import org.hibernate.hql.internal.CollectionSubqueryFactory;
import org.hibernate.hql.internal.NameGenerator;
import org.hibernate.hql.internal.antlr.HqlSqlTokenTypes;
import org.hibernate.hql.internal.ast.HqlSqlWalker;
import org.hibernate.hql.internal.ast.util.SessionFactoryHelper;
import org.hibernate.internal.CoreLogging;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.internal.log.DeprecationLogger;
import org.hibernate.internal.util.collections.ArrayHelper;
import org.hibernate.loader.PropertyPath;
import org.hibernate.param.ParameterSpecification;
import org.hibernate.persister.collection.CollectionPropertyMapping;
import org.hibernate.persister.collection.CollectionPropertyNames;
Expand All @@ -33,6 +30,8 @@
import org.hibernate.persister.entity.Joinable;
import org.hibernate.persister.entity.PropertyMapping;
import org.hibernate.persister.entity.Queryable;
import org.hibernate.tuple.IdentifierProperty;
import org.hibernate.type.EmbeddedComponentType;
import org.hibernate.type.EntityType;
import org.hibernate.type.Type;

Expand Down Expand Up @@ -130,18 +129,22 @@ public Queryable getQueryable() {
String renderScalarIdentifierSelect(int i) {
checkInitialized();

final String idPropertyName = getIdentifierPropertyName();
String[] cols = getPropertyMapping( idPropertyName ).toColumns( getTableAlias(), idPropertyName );

final String[] idPropertyName = getIdentifierPropertyNames();
StringBuilder buf = new StringBuilder();
// For property references generate <tablealias>.<columnname> as <projectionalias>
for ( int j = 0; j < cols.length; j++ ) {
String column = cols[j];
if ( j > 0 ) {
buf.append( ", " );
int counter = 0;
for ( int j = 0; j < idPropertyName.length; j++ ) {
String propertyName = idPropertyName[j];
String[] toColumns = getPropertyMapping( propertyName ).toColumns( getTableAlias(), propertyName );
for ( int h = 0; h < toColumns.length; h++, counter++ ) {
String column = toColumns[h];
if ( j + h > 0 ) {
buf.append( ", " );
}
buf.append( column ).append( " as " ).append( NameGenerator.scalarName( i, counter ) );
}
buf.append( column ).append( " as " ).append( NameGenerator.scalarName( i, j ) );
}

LOG.debug( "Rendered scalar ID select column(s): " + buf );
return buf.toString();
}

Expand Down Expand Up @@ -682,13 +685,25 @@ public String[] toColumns(String propertyName) throws QueryException, Unsupporte
}
}

public String getIdentifierPropertyName() {
if ( getEntityPersister() != null && getEntityPersister().getEntityMetamodel() != null
&& getEntityPersister().getEntityMetamodel().hasNonIdentifierPropertyNamedId() ) {
return getEntityPersister().getIdentifierPropertyName();
}
else {
return EntityPersister.ENTITY_ID;
public String[] getIdentifierPropertyNames() {
if ( getEntityPersister() != null ) {
String identifierPropertyName = getEntityPersister().getIdentifierPropertyName();
if ( identifierPropertyName != null ) {
return new String[] { identifierPropertyName };
}
else {
final IdentifierProperty identifierProperty = getEntityPersister().getEntityMetamodel()
.getIdentifierProperty();
if ( identifierProperty.hasIdentifierMapper() && !identifierProperty.isEmbedded() ) {
return new String[] { PropertyPath.IDENTIFIER_MAPPER_PROPERTY };
}
else {
if ( EmbeddedComponentType.class.isInstance( identifierProperty.getType() ) ) {
return ( (EmbeddedComponentType) identifierProperty.getType() ).getPropertyNames();
}
}
}
}
return new String[] { EntityPersister.ENTITY_ID };
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2289,7 +2289,7 @@ protected void initSubclassPropertyAliasesMap(PersistentClass model) throws Mapp
new String[] {idColumnNames[i]}
);
}
// if (hasIdentifierProperty() && !ENTITY_ID.equals( getIdentifierPropertyName() ) ) {
// if (hasIdentifierProperty() && !ENTITY_ID.equals( getIdentifierPropertyNames() ) ) {
if ( hasIdentifierProperty() ) {
subclassPropertyAliases.put(
getIdentifierPropertyName() + "." + idPropertyNames[i],
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.test.ecid;

import java.io.Serializable;
import java.util.Iterator;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinColumns;
import javax.persistence.ManyToOne;

import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
import org.junit.Test;

import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

/**
* @author Gail Badner
*/
public class CompositeIdAssociationsWithEmbeddedCompositeIdTest extends BaseCoreFunctionalTestCase {

@Override
protected Class<?>[] getAnnotatedClasses() {
return new Class<?>[] { Parent.class, Person.class };
}

@Test
@TestForIssue( jiraKey = "HHH-13114")
public void testQueries() {
Parent parent1 = new Parent( "Jane", 0 );
Parent parent2 = new Parent( "Jim", 1 );
Person person = doInHibernate(
this::sessionFactory, session -> {
Person p = new Person();
p.setParent1( parent1 );
p.setParent2( parent2 );
p.setBirthOrder( 0 );
session.persist( parent1 );
session.persist( parent2 );
session.persist( p );
return p;
});

doInHibernate(
this::sessionFactory, session -> {
checkResult( session.get( Person.class, person ) );
});


doInHibernate(
this::sessionFactory, session -> {
checkResult( session.createQuery( "from Person p", Person.class ).getSingleResult() );
});

doInHibernate(
this::sessionFactory, session -> {
Iterator<Person> iterator = session.createQuery( "from Person p", Person.class ).iterate();
assertTrue( iterator.hasNext() );
Person p = iterator.next();
checkResult( p );
assertFalse( iterator.hasNext() );
});
}

private void checkResult(Person p) {
assertEquals( "Jane", p.getParent1().name );
assertEquals( 0, p.getParent1().index );
assertEquals( "Jim", p.getParent2().name );
assertEquals( 1, p.getParent2().index );
}

@Entity(name = "Person")
public static class Person implements Serializable {
@Id
@JoinColumns( value = {
@JoinColumn(name = "p1Name"),
@JoinColumn(name = "p1Index")
})
@ManyToOne
private Parent parent1;

@Id
@JoinColumns( value = {
@JoinColumn(name = "p2Name"),
@JoinColumn(name = "p2Index")
})
@ManyToOne
private Parent parent2;

@Id
private int birthOrder;

private String name;

public Person() {
}

public Person(String name, Parent parent1, Parent parent2) {
this();
setName( name );
this.parent1 = parent1;
this.parent2 = parent2;
}

public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}

public Parent getParent1() {
return parent1;
}
public void setParent1(Parent parent1) {
this.parent1 = parent1;
}

public Parent getParent2() {
return parent2;
}
public void setParent2(Parent parent2) {
this.parent2 = parent2;
}

public int getBirthOrder() {
return birthOrder;
}
public void setBirthOrder(int birthOrder) {
this.birthOrder = birthOrder;
}
}

@Entity(name = "Parent")
public static class Parent implements Serializable {
@Id
private String name;

@Id
private int index;

public Parent() {
}

public Parent(String name, int index) {
this.name = name;
this.index = index;
}
}
}
Loading