Fix AbstractEntityPersister#findSubpart returning the wrong ModelPart when the Entity has an attribute named id that it is not the identifier

This commit is contained in:
Andrea Boriero 2021-06-10 14:43:15 +02:00
parent 055ba6da71
commit 0e6561baf4
7 changed files with 182 additions and 108 deletions

View File

@ -6726,13 +6726,23 @@ public abstract class AbstractEntityPersister
public ModelPart findSubPart(String name, EntityMappingType treatTargetType) {
LOG.tracef( "#findSubPart(`%s`)", name );
final AttributeMapping declaredAttribute = declaredAttributeMappings.get( name );
if ( declaredAttribute != null ) {
return declaredAttribute;
}
if ( isIdentifierReference( name ) ) {
return identifierMapping;
}
final AttributeMapping declaredAttribute = declaredAttributeMappings.get( name );
if ( declaredAttribute != null ) {
return declaredAttribute;
if ( identifierMapping instanceof NonAggregatedIdentifierMappingImpl ) {
final ModelPart subPart = ( (NonAggregatedIdentifierMappingImpl) identifierMapping ).findSubPart(
name,
treatTargetType
);
if ( subPart != null ) {
return subPart;
}
}
if ( superMappingType != null ) {
@ -6752,10 +6762,6 @@ public abstract class AbstractEntityPersister
}
}
if ( identifierMapping instanceof NonAggregatedIdentifierMappingImpl ) {
return ( (NonAggregatedIdentifierMappingImpl) identifierMapping ).findSubPart( name, treatTargetType );
}
if ( EntityDiscriminatorMapping.matchesRoleName( name ) ) {
return discriminatorMapping;
}

View File

@ -4,7 +4,7 @@
* 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.idprops;
package org.hibernate.orm.test.idprops;
import java.io.Serializable;
import javax.persistence.Embeddable;
@ -12,45 +12,57 @@ import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
import org.junit.Before;
import org.junit.Test;
import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.SessionFactory;
import org.hibernate.testing.orm.junit.SessionFactoryScope;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate;
import static org.junit.Assert.assertEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
/**
* @author Gail Badner
*/
public class PropertyNamedIdInEmbeddedIdTest extends BaseCoreFunctionalTestCase {
@Override
public Class[] getAnnotatedClasses() {
return new Class[] { Person.class };
}
@DomainModel(
annotatedClasses = PropertyNamedIdInEmbeddedIdTest.Person.class
)
@SessionFactory
public class PropertyNamedIdInEmbeddedIdTest {
@Before
public void setUp() {
doInHibernate( this::sessionFactory, session -> {
@BeforeEach
public void setUp(SessionFactoryScope scope) {
scope.inTransaction( session -> {
session.persist( new Person( "John Doe", 0 ) );
session.persist( new Person( "John Doe", 1 ) );
session.persist( new Person( "Jane Doe", 0 ) );
} );
}
@AfterEach
public void tearDown(SessionFactoryScope scope) {
scope.inTransaction(
session ->
session.createQuery( "delete from Person" ).executeUpdate()
);
}
@Test
@TestForIssue(jiraKey = "HHH-13084")
public void testHql() {
doInHibernate( this::sessionFactory, session -> {
public void testHql(SessionFactoryScope scope) {
scope.inTransaction( session -> {
assertEquals(
1, session.createQuery( "from Person p where p.id = :id", Person.class )
1,
session.createQuery( "from Person p where p.id = :id", Person.class )
.setParameter( "id", new PersonId( "John Doe", 0 ) )
.list()
.size()
);
assertEquals(
2, session.createQuery( "from Person p where p.id.id = :id", Person.class )
2,
session.createQuery( "from Person p where p.id.id = :id", Person.class )
.setParameter( "id", 0 )
.list()
.size()

View File

@ -4,7 +4,7 @@
* 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.idprops;
package org.hibernate.orm.test.idprops;
import java.io.Serializable;
import javax.persistence.Entity;
@ -12,35 +12,45 @@ import javax.persistence.Id;
import javax.persistence.IdClass;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
import org.junit.Before;
import org.junit.Test;
import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.SessionFactory;
import org.hibernate.testing.orm.junit.SessionFactoryScope;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate;
import static org.junit.Assert.assertEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
/**
* @author Gail Badner
*/
public class PropertyNamedIdInIdClassTest extends BaseCoreFunctionalTestCase {
@Override
public Class[] getAnnotatedClasses() {
return new Class[] { Person.class };
}
@DomainModel(
annotatedClasses = PropertyNamedIdInIdClassTest.Person.class
)
@SessionFactory
public class PropertyNamedIdInIdClassTest {
@Before
public void setUp() {
doInHibernate( this::sessionFactory, session -> {
@BeforeEach
public void setUp(SessionFactoryScope scope) {
scope.inTransaction( session -> {
session.persist( new Person( "John Doe", 0 ) );
session.persist( new Person( "John Doe", 1 ) );
session.persist( new Person( "Jane Doe", 0 ) );
} );
}
@AfterEach
public void tearDown(SessionFactoryScope scope) {
scope.inTransaction(
session ->
session.createQuery( "delete from Person" ).executeUpdate()
);
}
@Test
@TestForIssue(jiraKey = "HHH-13084")
public void testHql() {
doInHibernate( this::sessionFactory, session -> {
public void testHql(SessionFactoryScope scope) {
scope.inTransaction( session -> {
assertEquals( 2, session.createQuery( "from Person p where p.id = 0", Person.class ).list().size() );
assertEquals( 3L, session.createQuery( "select count( p ) from Person p" ).uniqueResult() );

View File

@ -4,42 +4,52 @@
* 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.idprops;
package org.hibernate.orm.test.idprops;
import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.Id;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
import org.junit.Before;
import org.junit.Test;
import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.SessionFactory;
import org.hibernate.testing.orm.junit.SessionFactoryScope;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate;
import static org.junit.Assert.assertEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
/**
* @author Gail Badner
*/
public class PropertyNamedIdInNonJpaCompositeIdTest extends BaseCoreFunctionalTestCase {
@Override
public Class[] getAnnotatedClasses() {
return new Class[] { Person.class };
}
@DomainModel(
annotatedClasses = PropertyNamedIdInNonJpaCompositeIdTest.Person.class
)
@SessionFactory
public class PropertyNamedIdInNonJpaCompositeIdTest {
@Before
public void setUp() {
doInHibernate( this::sessionFactory, session -> {
@BeforeEach
public void setUp(SessionFactoryScope scope) {
scope.inTransaction( session -> {
session.persist( new Person( "John Doe", 0 ) );
session.persist( new Person( "John Doe", 1 ) );
session.persist( new Person( "Jane Doe", 0 ) );
} );
}
@AfterEach
public void tearDown(SessionFactoryScope scope) {
scope.inTransaction(
session ->
session.createQuery( "delete from Person" ).executeUpdate()
);
}
@Test
@TestForIssue(jiraKey = "HHH-13084")
public void testHql() {
doInHibernate( this::sessionFactory, session -> {
public void testHql(SessionFactoryScope scope) {
scope.inTransaction( session -> {
assertEquals( 2, session.createQuery( "from Person p where p.id = 0", Person.class ).list().size() );
assertEquals( 3L, session.createQuery( "select count( p ) from Person p" ).uniqueResult() );

View File

@ -4,7 +4,7 @@
* 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.idprops;
package org.hibernate.orm.test.idprops;
import java.io.Serializable;
import javax.persistence.Column;
@ -13,37 +13,48 @@ import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
import org.junit.Before;
import org.junit.Test;
import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.SessionFactory;
import org.hibernate.testing.orm.junit.SessionFactoryScope;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate;
import static org.junit.Assert.assertEquals;
/**
* @author Gail Badner
*/
public class PropertyNamedIdOutOfEmbeddedIdTest extends BaseCoreFunctionalTestCase {
@Override
public Class[] getAnnotatedClasses() {
return new Class[] { Person.class };
}
@DomainModel(
annotatedClasses = PropertyNamedIdOutOfEmbeddedIdTest.Person.class
)
@SessionFactory
public class PropertyNamedIdOutOfEmbeddedIdTest {
@Before
public void setUp() {
doInHibernate( this::sessionFactory, session -> {
@BeforeEach
public void setUp(SessionFactoryScope scope) {
scope.inTransaction( session -> {
session.persist( new Person( "John Doe", 0, 6 ) );
session.persist( new Person( "John Doe", 1, 6 ) );
session.persist( new Person( "Jane Doe", 0 ) );
} );
}
@AfterEach
public void tearDown(SessionFactoryScope scope) {
scope.inTransaction(
session ->
session.createQuery( "delete from Person" ).executeUpdate()
);
}
@Test
@TestForIssue(jiraKey = "HHH-13084")
public void testHql() {
doInHibernate( this::sessionFactory, session -> {
public void testHql(SessionFactoryScope scope) {
scope.inTransaction( session -> {
assertEquals(
2, session.createQuery( "from Person p where p.id = :id", Person.class )
2,
session.createQuery( "from Person p where p.id = :id", Person.class )
.setParameter( "id", 6 )
.list()
.size()

View File

@ -4,7 +4,7 @@
* 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.idprops;
package org.hibernate.orm.test.idprops;
import java.io.Serializable;
import javax.persistence.Column;
@ -13,38 +13,53 @@ import javax.persistence.Id;
import javax.persistence.IdClass;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
import org.junit.Before;
import org.junit.Test;
import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.SessionFactory;
import org.hibernate.testing.orm.junit.SessionFactoryScope;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate;
import static org.junit.Assert.assertEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
/**
* @author Gail Badner
*/
public class PropertyNamedIdOutOfIdClassTest extends BaseCoreFunctionalTestCase {
@Override
public Class[] getAnnotatedClasses() {
return new Class[] { Person.class };
}
@DomainModel(
annotatedClasses = PropertyNamedIdOutOfIdClassTest.Person.class
)
@SessionFactory
public class PropertyNamedIdOutOfIdClassTest {
@Before
public void setUp() {
doInHibernate( this::sessionFactory, session -> {
@BeforeEach
public void setUp(SessionFactoryScope scope) {
scope.inTransaction( session -> {
session.persist( new Person( "John Doe", 0 ) );
session.persist( new Person( "John Doe", 1, 1 ) );
session.persist( new Person( "John Doe", 2, 2 ) );
} );
}
@AfterEach
public void tearDown(SessionFactoryScope scope) {
scope.inTransaction(
session ->
session.createQuery( "delete from Person" ).executeUpdate()
);
}
@Test
@TestForIssue(jiraKey = "HHH-13084")
public void testHql() {
doInHibernate( this::sessionFactory, session -> {
assertEquals( 1, session.createQuery( "from Person p where p.id is null", Person.class ).list().size() );
assertEquals( 2, session.createQuery( "from Person p where p.id is not null", Person.class ).list().size() );
public void testHql(SessionFactoryScope scope) {
scope.inTransaction( session -> {
assertEquals(
1,
session.createQuery( "from Person p where p.id is null", Person.class ).list().size()
);
assertEquals(
2,
session.createQuery( "from Person p where p.id is not null", Person.class ).list().size()
);
assertEquals( 3L, session.createQuery( "select count( p ) from Person p" ).uniqueResult() );
} );
}

View File

@ -4,42 +4,52 @@
* 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.idprops;
package org.hibernate.orm.test.idprops;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
import org.junit.Before;
import org.junit.Test;
import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.SessionFactory;
import org.hibernate.testing.orm.junit.SessionFactoryScope;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
/**
* @author Gail Badner
*/
public class PropertyNamedIdOutOfNonJpaCompositeIdTest extends BaseCoreFunctionalTestCase {
@Override
public Class[] getAnnotatedClasses() {
return new Class[] { Person.class };
}
@DomainModel(
annotatedClasses = PropertyNamedIdOutOfNonJpaCompositeIdTest.Person.class
)
@SessionFactory
public class PropertyNamedIdOutOfNonJpaCompositeIdTest {
@Before
public void setUp() {
doInHibernate( this::sessionFactory, session -> {
@BeforeEach
public void setUp(SessionFactoryScope scope) {
scope.inTransaction( session -> {
session.persist( new Person( "John Doe", 0 ) );
session.persist( new Person( "John Doe", 1, 1 ) );
session.persist( new Person( "John Doe", 2, 2 ) );
} );
}
@AfterEach
public void tearDown(SessionFactoryScope scope) {
scope.inTransaction(
session ->
session.createQuery( "delete from Person" ).executeUpdate()
);
}
@Test
public void testHql() {
doInHibernate( this::sessionFactory, session -> {
public void testHql(SessionFactoryScope scope) {
scope.inTransaction( session -> {
assertEquals( 1, session.createQuery( "from Person p where p.id = 1", Person.class ).list().size() );
assertEquals( 3L, session.createQuery( "select count( p ) from Person p" ).uniqueResult() );