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-14 08:26:07 +02:00
parent 0e6561baf4
commit babefc8b9d
13 changed files with 351 additions and 255 deletions

View File

@ -6726,15 +6726,57 @@ public abstract class AbstractEntityPersister
public ModelPart findSubPart(String name, EntityMappingType treatTargetType) { public ModelPart findSubPart(String name, EntityMappingType treatTargetType) {
LOG.tracef( "#findSubPart(`%s`)", name ); LOG.tracef( "#findSubPart(`%s`)", name );
if ( EntityDiscriminatorMapping.matchesRoleName( name ) ) {
return discriminatorMapping;
}
final AttributeMapping declaredAttribute = declaredAttributeMappings.get( name ); final AttributeMapping declaredAttribute = declaredAttributeMappings.get( name );
if ( declaredAttribute != null ) { if ( declaredAttribute != null ) {
return declaredAttribute; return declaredAttribute;
} }
if ( isIdentifierReference( name ) ) { if ( superMappingType != null ) {
return identifierMapping; final ModelPart superDefinedAttribute = superMappingType.findSubPart( name, superMappingType );
if ( superDefinedAttribute != null ) {
return superDefinedAttribute;
}
}
else {
if ( subclassMappingTypes != null && !subclassMappingTypes.isEmpty() ) {
for ( EntityMappingType subMappingType : subclassMappingTypes.values() ) {
final ModelPart subDefinedAttribute = subMappingType.findSubTypesSubPart( name, treatTargetType );
if ( subDefinedAttribute != null ) {
return subDefinedAttribute;
}
}
}
} }
return getIdentifierModelPart( name, treatTargetType );
}
@Override
public ModelPart findSubTypesSubPart(String name, EntityMappingType treatTargetType) {
final AttributeMapping declaredAttribute = declaredAttributeMappings.get( name );
if ( declaredAttribute != null ) {
return declaredAttribute;
}
if ( subclassMappingTypes != null && !subclassMappingTypes.isEmpty() ) {
for ( EntityMappingType subMappingType : subclassMappingTypes.values() ) {
final ModelPart subDefinedAttribute = subMappingType.findSubTypesSubPart( name, treatTargetType );
if ( subDefinedAttribute != null ) {
return subDefinedAttribute;
}
}
}
return null;
}
private ModelPart getIdentifierModelPart(String name, EntityMappingType treatTargetType) {
if ( identifierMapping instanceof NonAggregatedIdentifierMappingImpl ) { if ( identifierMapping instanceof NonAggregatedIdentifierMappingImpl ) {
final ModelPart subPart = ( (NonAggregatedIdentifierMappingImpl) identifierMapping ).findSubPart( final ModelPart subPart = ( (NonAggregatedIdentifierMappingImpl) identifierMapping ).findSubPart(
name, name,
@ -6745,51 +6787,10 @@ public abstract class AbstractEntityPersister
} }
} }
if ( superMappingType != null ) {
final ModelPart superDefinedAttribute = superMappingType.findSubPart( name, superMappingType );
if ( superDefinedAttribute != null ) {
return superDefinedAttribute;
}
}
if ( subclassMappingTypes != null && !subclassMappingTypes.isEmpty() ) {
for ( EntityMappingType subMappingType : subclassMappingTypes.values() ) {
final ModelPart subDefinedAttribute = subMappingType.findSubTypesSubPart( name, treatTargetType );
if ( subDefinedAttribute != null ) {
return subDefinedAttribute;
}
}
}
if ( EntityDiscriminatorMapping.matchesRoleName( name ) ) {
return discriminatorMapping;
}
return null;
}
@Override
public ModelPart findSubTypesSubPart(String name, EntityMappingType treatTargetType) {
if ( isIdentifierReference( name ) ) { if ( isIdentifierReference( name ) ) {
return identifierMapping; return identifierMapping;
} }
final AttributeMapping declaredAttribute = declaredAttributeMappings.get( name );
if ( declaredAttribute != null ) {
return declaredAttribute;
}
if ( subclassMappingTypes != null && !subclassMappingTypes.isEmpty() ) {
for ( EntityMappingType subMappingType : subclassMappingTypes.values() ) {
final ModelPart subDefinedAttribute = subMappingType.findSubTypesSubPart( name, treatTargetType );
if ( subDefinedAttribute != null ) {
return subDefinedAttribute;
}
}
}
return null; return null;
} }
@ -6798,12 +6799,12 @@ public abstract class AbstractEntityPersister
return true; return true;
} }
if ( entityMetamodel.hasNonIdentifierPropertyNamedId() ) { if ( hasIdentifierProperty() && getIdentifierPropertyName().equals( name ) ) {
return "id".equals( name ); return true;
} }
if ( hasIdentifierProperty() ) { if ( !entityMetamodel.hasNonIdentifierPropertyNamedId() && "id".equals( name ) ) {
return getIdentifierPropertyName().equals( name ); return true;
} }
return false; return false;

View File

@ -4,7 +4,7 @@
* License: GNU Lesser General Public License (LGPL), version 2.1 or later. * 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>. * 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 javax.persistence.Column; import javax.persistence.Column;
import javax.persistence.Entity; import javax.persistence.Entity;
@ -15,35 +15,47 @@ import javax.persistence.Inheritance;
import javax.persistence.InheritanceType; import javax.persistence.InheritanceType;
import org.hibernate.testing.TestForIssue; import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; import org.hibernate.testing.orm.junit.DomainModel;
import org.junit.Before; import org.hibernate.testing.orm.junit.SessionFactory;
import org.junit.Test; 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.jupiter.api.Assertions.assertEquals;
import static org.junit.Assert.assertEquals;
/** /**
* @author Gail Badner * @author Gail Badner
*/ */
public class IdPropertyInJoinedSubclassTest extends BaseCoreFunctionalTestCase { @DomainModel(
@Override annotatedClasses = {
public Class[] getAnnotatedClasses() { IdPropertyInJoinedSubclassTest.Human.class,
return new Class[] { Human.class, Genius.class }; IdPropertyInJoinedSubclassTest.Genius.class
} }
)
@SessionFactory
public class IdPropertyInJoinedSubclassTest {
@Before @BeforeEach
public void setUp() { public void setUp(SessionFactoryScope scope) {
doInHibernate( this::sessionFactory, session -> { scope.inTransaction( session -> {
session.persist( new Genius() ); session.persist( new Genius() );
session.persist( new Genius( 1L ) ); session.persist( new Genius( 1L ) );
session.persist( new Genius( 1L ) ); session.persist( new Genius( 1L ) );
} ); } );
} }
@AfterEach
public void tearDown(SessionFactoryScope scope) {
scope.inTransaction( session -> {
session.createQuery( "delete from Genius" ).executeUpdate();
} );
}
@Test @Test
@TestForIssue(jiraKey = "HHH-13114") @TestForIssue(jiraKey = "HHH-13114")
public void testHql() { public void testHql(SessionFactoryScope scope) {
doInHibernate( this::sessionFactory, session -> { scope.inTransaction( session -> {
assertEquals( assertEquals(
2, session.createQuery( "from Genius g where g.id = :id", Genius.class ) 2, session.createQuery( "from Genius g where g.id = :id", Genius.class )
.setParameter( "id", 1L ) .setParameter( "id", 1L )
@ -82,6 +94,8 @@ public class IdPropertyInJoinedSubclassTest extends BaseCoreFunctionalTestCase {
private Long realId; private Long realId;
private String name;
@Id @Id
@GeneratedValue(strategy = GenerationType.AUTO) @GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "realId") @Column(name = "realId")
@ -98,6 +112,8 @@ public class IdPropertyInJoinedSubclassTest extends BaseCoreFunctionalTestCase {
public static class Genius extends Human { public static class Genius extends Human {
private Long id; private Long id;
private int age;
public Genius() { public Genius() {
} }

View File

@ -0,0 +1,141 @@
/*
* 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.orm.test.idprops;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import org.hibernate.testing.TestForIssue;
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;
/**
* @author Gail Badner
*/
@DomainModel(
annotatedClasses = {
IdPropertyInSingleTableSubclassTest.Human.class,
IdPropertyInSingleTableSubclassTest.Genius.class
}
)
@SessionFactory
public class IdPropertyInSingleTableSubclassTest {
@BeforeEach
public void setUp(SessionFactoryScope scope) {
scope.inTransaction( session -> {
session.persist( new Genius() );
session.persist( new Genius( 1L ) );
session.persist( new Genius( 1L ) );
} );
}
@AfterEach
public void tearDown(SessionFactoryScope scope) {
scope.inTransaction(
session ->
session.createQuery( "delete from Genius" ).executeUpdate()
);
}
@Test
@TestForIssue(jiraKey = "HHH-13114")
public void testHql(SessionFactoryScope scope) {
scope.inTransaction(
session -> {
assertEquals(
2,
session.createQuery(
"from Genius g where g.id = :id",
Genius.class
)
.setParameter( "id", 1L )
.list()
.size()
);
assertEquals(
1,
session.createQuery( "from Genius g where g.id is null", Genius.class )
.list()
.size()
);
assertEquals( 3L, session.createQuery( "select count( g ) from Genius g" ).uniqueResult() );
assertEquals(
2,
session.createQuery( "from Human h where h.id = :id", Human.class )
.setParameter( "id", 1L )
.list()
.size()
);
assertEquals(
1,
session.createQuery( "from Human h where h.id is null", Human.class )
.list()
.size()
);
assertEquals( 3L, session.createQuery( "select count( h ) from Human h" ).uniqueResult() );
} );
}
@Entity(name = "Human")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
public static class Human {
private Long realId;
private String name;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "realId")
public Long getRealId() {
return realId;
}
public void setRealId(Long realId) {
this.realId = realId;
}
}
@Entity(name = "Genius")
public static class Genius extends Human {
private Long id;
private int age;
public Genius() {
}
public Genius(Long id) {
this.id = id;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
}
}

View File

@ -4,7 +4,7 @@
* License: GNU Lesser General Public License (LGPL), version 2.1 or later. * 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>. * 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 javax.persistence.Column; import javax.persistence.Column;
import javax.persistence.Entity; import javax.persistence.Entity;
@ -16,44 +16,59 @@ import javax.persistence.InheritanceType;
import javax.persistence.MappedSuperclass; import javax.persistence.MappedSuperclass;
import org.hibernate.testing.TestForIssue; import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; import org.hibernate.testing.orm.junit.DomainModel;
import org.junit.Before; import org.hibernate.testing.orm.junit.SessionFactory;
import org.junit.Test; 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.jupiter.api.Assertions.assertEquals;
import static org.junit.Assert.assertEquals;
/** /**
* @author Gail Badner * @author Gail Badner
*/ */
public class IdPropertyInSubclassIdInMappedSuperclassTest extends BaseCoreFunctionalTestCase { @DomainModel(
@Override annotatedClasses = {
public Class[] getAnnotatedClasses() { IdPropertyInSubclassIdInMappedSuperclassTest.Human.class,
return new Class[] { Human.class, Genius.class }; IdPropertyInSubclassIdInMappedSuperclassTest.Genius.class
} }
)
@SessionFactory
public class IdPropertyInSubclassIdInMappedSuperclassTest {
@Before @BeforeEach
public void setUp() { public void setUp(SessionFactoryScope scope) {
doInHibernate( this::sessionFactory, session -> { scope.inTransaction( session -> {
session.persist( new Genius() ); session.persist( new Genius() );
session.persist( new Genius( 1L ) ); session.persist( new Genius( 1L ) );
session.persist( new Genius( 1L ) ); session.persist( new Genius( 1L ) );
} ); } );
} }
@AfterEach
public void tearDown(SessionFactoryScope scope) {
scope.inTransaction(
session ->
session.createQuery( "delete from Genius" ).executeUpdate()
);
}
@Test @Test
@TestForIssue(jiraKey = "HHH-13114") @TestForIssue(jiraKey = "HHH-13114")
public void testHql() { public void testHql(SessionFactoryScope scope) {
doInHibernate( this::sessionFactory, session -> { scope.inTransaction( session -> {
assertEquals( assertEquals(
2, session.createQuery( "from Genius g where g.id = :id", Genius.class ) 2,
session.createQuery( "from Genius g where g.id = :id", Genius.class )
.setParameter( "id", 1L ) .setParameter( "id", 1L )
.list() .list()
.size() .size()
); );
assertEquals( assertEquals(
1, session.createQuery( "from Genius g where g.id is null", Genius.class ) 1,
session.createQuery( "from Genius g where g.id is null", Genius.class )
.list() .list()
.size() .size()
); );
@ -61,14 +76,16 @@ public class IdPropertyInSubclassIdInMappedSuperclassTest extends BaseCoreFuncti
assertEquals( 3L, session.createQuery( "select count( g ) from Genius g" ).uniqueResult() ); assertEquals( 3L, session.createQuery( "select count( g ) from Genius g" ).uniqueResult() );
assertEquals( assertEquals(
2, session.createQuery( "from Human h where h.id = :id", Human.class ) 2,
session.createQuery( "from Human h where h.id = :id", Human.class )
.setParameter( "id", 1L ) .setParameter( "id", 1L )
.list() .list()
.size() .size()
); );
assertEquals( assertEquals(
1, session.createQuery( "from Human h where h.id is null", Human.class ) 1,
session.createQuery( "from Human h where h.id is null", Human.class )
.list() .list()
.size() .size()
); );
@ -83,6 +100,8 @@ public class IdPropertyInSubclassIdInMappedSuperclassTest extends BaseCoreFuncti
private Long realId; private Long realId;
private String description;
@Id @Id
@GeneratedValue(strategy = GenerationType.AUTO) @GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "realId") @Column(name = "realId")
@ -98,12 +117,15 @@ public class IdPropertyInSubclassIdInMappedSuperclassTest extends BaseCoreFuncti
@Entity(name = "Human") @Entity(name = "Human")
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public static class Human extends Animal { public static class Human extends Animal {
private String name;
} }
@Entity(name = "Genius") @Entity(name = "Genius")
public static class Genius extends Human { public static class Genius extends Human {
private Long id; private Long id;
private int age;
public Genius() { public Genius() {
} }

View File

@ -4,7 +4,7 @@
* License: GNU Lesser General Public License (LGPL), version 2.1 or later. * 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>. * 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 javax.persistence.Column; import javax.persistence.Column;
import javax.persistence.Entity; import javax.persistence.Entity;
@ -15,44 +15,59 @@ import javax.persistence.Inheritance;
import javax.persistence.InheritanceType; import javax.persistence.InheritanceType;
import org.hibernate.testing.TestForIssue; import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; import org.hibernate.testing.orm.junit.DomainModel;
import org.junit.Before; import org.hibernate.testing.orm.junit.SessionFactory;
import org.junit.Test; 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.jupiter.api.Assertions.assertEquals;
import static org.junit.Assert.assertEquals;
/** /**
* @author Gail Badner * @author Gail Badner
*/ */
public class IdPropertyInTablePerClassSubclassTest extends BaseCoreFunctionalTestCase { @DomainModel(
@Override annotatedClasses = {
public Class[] getAnnotatedClasses() { IdPropertyInTablePerClassSubclassTest.Human.class,
return new Class[] { Human.class, Genius.class }; IdPropertyInTablePerClassSubclassTest.Genius.class
} }
)
@SessionFactory
public class IdPropertyInTablePerClassSubclassTest {
@Before @BeforeEach
public void setUp() { public void setUp(SessionFactoryScope scope) {
doInHibernate( this::sessionFactory, session -> { scope.inTransaction( session -> {
session.persist( new Genius() ); session.persist( new Genius() );
session.persist( new Genius( 1L ) ); session.persist( new Genius( 1L ) );
session.persist( new Genius( 1L ) ); session.persist( new Genius( 1L ) );
} ); } );
} }
@AfterEach
public void tearDown(SessionFactoryScope scope) {
scope.inTransaction(
session ->
session.createQuery( "delete from Genius" ).executeUpdate()
);
}
@Test @Test
@TestForIssue(jiraKey = "HHH-13114") @TestForIssue(jiraKey = "HHH-13114")
public void testHql() { public void testHql(SessionFactoryScope scope) {
doInHibernate( this::sessionFactory, session -> { scope.inTransaction( session -> {
assertEquals( assertEquals(
2, session.createQuery( "from Genius g where g.id = :id", Genius.class ) 2,
session.createQuery( "from Genius g where g.id = :id", Genius.class )
.setParameter( "id", 1L ) .setParameter( "id", 1L )
.list() .list()
.size() .size()
); );
assertEquals( assertEquals(
1, session.createQuery( "from Genius g where g.id is null", Genius.class ) 1,
session.createQuery( "from Genius g where g.id is null", Genius.class )
.list() .list()
.size() .size()
); );
@ -60,14 +75,16 @@ public class IdPropertyInTablePerClassSubclassTest extends BaseCoreFunctionalTes
assertEquals( 3L, session.createQuery( "select count( g ) from Genius g" ).uniqueResult() ); assertEquals( 3L, session.createQuery( "select count( g ) from Genius g" ).uniqueResult() );
assertEquals( assertEquals(
2, session.createQuery( "from Human h where h.id = :id", Human.class ) 2,
session.createQuery( "from Human h where h.id = :id", Human.class )
.setParameter( "id", 1L ) .setParameter( "id", 1L )
.list() .list()
.size() .size()
); );
assertEquals( assertEquals(
1, session.createQuery( "from Human h where h.id is null", Human.class ) 1,
session.createQuery( "from Human h where h.id is null", Human.class )
.list() .list()
.size() .size()
); );
@ -82,6 +99,8 @@ public class IdPropertyInTablePerClassSubclassTest extends BaseCoreFunctionalTes
public static class Human { public static class Human {
private Long realId; private Long realId;
private String name;
@Id @Id
@GeneratedValue(strategy = GenerationType.AUTO) @GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "realId") @Column(name = "realId")
@ -98,6 +117,8 @@ public class IdPropertyInTablePerClassSubclassTest extends BaseCoreFunctionalTes
public static class Genius extends Human { public static class Genius extends Human {
private Long id; private Long id;
private int age;
public Genius() { public Genius() {
} }

View File

@ -4,7 +4,7 @@
* License: GNU Lesser General Public License (LGPL), version 2.1 or later. * 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>. * 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;
/** /**

View File

@ -4,7 +4,7 @@
* License: GNU Lesser General Public License (LGPL), version 2.1 or later. * 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>. * 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 java.io.Serializable;
/** /**

View File

@ -8,7 +8,7 @@
--> -->
<!DOCTYPE hibernate-mapping SYSTEM "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd" > <!DOCTYPE hibernate-mapping SYSTEM "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd" >
<hibernate-mapping package="org.hibernate.test.idprops"> <hibernate-mapping package="org.hibernate.orm.test.idprops">
<!-- <!--
Person has an identitifer property named something other than 'id'; Person has an identitifer property named something other than 'id';

View File

@ -4,7 +4,7 @@
* License: GNU Lesser General Public License (LGPL), version 2.1 or later. * 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>. * 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.util.Date; import java.util.Date;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;

View File

@ -4,7 +4,7 @@
* License: GNU Lesser General Public License (LGPL), version 2.1 or later. * 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>. * 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;
/** /**

View File

@ -22,7 +22,6 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
/** /**
* @author Andrea Boriero * @author Andrea Boriero
*/ */
@NotImplementedYet( reason = "non-aggregated composite-id not yet implemented" )
@DomainModel( @DomainModel(
annotatedClasses = { annotatedClasses = {
OneToOneWithDerivedIdentityTest.Person.class, OneToOneWithDerivedIdentityTest.Person.class,
@ -32,7 +31,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
@SessionFactory @SessionFactory
public class OneToOneWithDerivedIdentityTest { public class OneToOneWithDerivedIdentityTest {
private static final Integer PERSON_ID = 1; private static final Integer PERSON_ID = 0;
@Test @Test
public void testGet(SessionFactoryScope scope) { public void testGet(SessionFactoryScope scope) {
@ -57,7 +56,7 @@ public class OneToOneWithDerivedIdentityTest {
} ); } );
} }
@Entity @Entity(name="Person")
public static class Person { public static class Person {
@Id @Id
private Integer id; private Integer id;
@ -93,8 +92,8 @@ public class OneToOneWithDerivedIdentityTest {
} }
} }
@Entity @Entity(name="PersonInfo")
public class PersonInfo { public static class PersonInfo {
@Id @Id
@OneToOne @OneToOne
private Person id; private Person id;

View File

@ -1,116 +0,0 @@
/*
* 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.idprops;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
import org.junit.Before;
import org.junit.Test;
import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate;
import static org.junit.Assert.assertEquals;
/**
* @author Gail Badner
*/
public class IdPropertyInSingleTableSubclassTest extends BaseCoreFunctionalTestCase {
@Override
public Class[] getAnnotatedClasses() {
return new Class[] { Human.class, Genius.class };
}
@Before
public void setUp() {
doInHibernate( this::sessionFactory, session -> {
session.persist( new Genius() );
session.persist( new Genius( 1L ) );
session.persist( new Genius( 1L ) );
} );
}
@Test
@TestForIssue(jiraKey = "HHH-13114")
public void testHql() {
doInHibernate( this::sessionFactory, session -> {
assertEquals(
2, session.createQuery( "from Genius g where g.id = :id", Genius.class )
.setParameter( "id", 1L )
.list()
.size()
);
assertEquals(
1, session.createQuery( "from Genius g where g.id is null", Genius.class )
.list()
.size()
);
assertEquals( 3L, session.createQuery( "select count( g ) from Genius g" ).uniqueResult() );
assertEquals(
2, session.createQuery( "from Human h where h.id = :id", Human.class )
.setParameter( "id", 1L )
.list()
.size()
);
assertEquals(
1, session.createQuery( "from Human h where h.id is null", Human.class )
.list()
.size()
);
assertEquals( 3L, session.createQuery( "select count( h ) from Human h" ).uniqueResult() );
} );
}
@Entity(name = "Human")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
public static class Human {
private Long realId;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "realId")
public Long getRealId() {
return realId;
}
public void setRealId(Long realId) {
this.realId = realId;
}
}
@Entity(name = "Genius")
public static class Genius extends Human {
private Long id;
public Genius() {
}
public Genius(Long id) {
this.id = id;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
}
}

View File

@ -6,32 +6,46 @@
*/ */
package org.hibernate.test.idprops; package org.hibernate.test.idprops;
import javax.persistence.criteria.CriteriaQuery;
import org.junit.Test;
import org.hibernate.query.Query;
import org.hibernate.Session; import org.hibernate.Session;
import org.hibernate.orm.test.idprops.LineItem;
import org.hibernate.orm.test.idprops.Order;
import org.hibernate.orm.test.idprops.Person;
import org.hibernate.query.Query;
import org.hibernate.testing.DialectChecks; import org.hibernate.testing.orm.junit.DialectFeatureChecks;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; 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.Test;
import static org.junit.Assert.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
/** /**
* @author Steve Ebersole * @author Steve Ebersole
*/ */
public class IdentifierPropertyReferencesTest extends BaseCoreFunctionalTestCase { @DomainModel(
@Override xmlMappings = "org/hibernate/orm/test/idprops/Mapping.hbm.xml"
public String[] getMappings() { )
return new String[] { "idprops/Mapping.hbm.xml" }; @SessionFactory
public class IdentifierPropertyReferencesTest {
@AfterEach
public void tearDown(SessionFactoryScope scope){
scope.inTransaction(
session -> {
session.createQuery( "delete from Person" ).executeUpdate();
session.createQuery( "delete from LineItem" ).executeUpdate();
session.createQuery( "delete from Order" ).executeUpdate();
}
);
} }
@Test @Test
public void testHqlIdPropertyReferences() { public void testHqlIdPropertyReferences(SessionFactoryScope scope) {
Person p = new Person( new Long( 1 ), "steve", 123 ); Person p = new Person( new Long( 1 ), "steve", 123 );
Order o = new Order( new Long( 1 ), p ); Order o = new Order( new Long( 1 ), p );
inTransaction( scope.inTransaction(
s -> { s -> {
s.save( p ); s.save( p );
LineItem l = new LineItem( o, "my-product", 2 ); LineItem l = new LineItem( o, "my-product", 2 );
@ -40,27 +54,29 @@ public class IdentifierPropertyReferencesTest extends BaseCoreFunctionalTestCase
} }
); );
inTransaction( scope.inTransaction(
s -> { s -> {
long count = extractCount( s, "select count(*) from Person p where p.id = 123" ); long count = extractCount( s, "select count(*) from Person p where p.id = 123" );
assertEquals( "Person by id prop (non-identifier)", 1, count ); assertEquals( 1, count, "Person by id prop (non-identifier)" );
count = extractCount( s, "select count(*) from Person p where p.pk = 1" ); count = extractCount( s, "select count(*) from Person p where p.pk = 1" );
assertEquals( "Person by pk prop (identifier)", 1, count ); assertEquals( 1, count, "Person by pk prop (identifier)" );
count = extractCount( s, "select count(*) from Order o where o.id = 1" ); count = extractCount( s, "select count(*) from Order o where o.id = 1" );
assertEquals( "Order by number prop (named identifier)", 1, count ); assertEquals( 1, count, "Order by number prop (named identifier)" );
count = extractCount( s, "select count(*) from Order o where o.number = 1" ); count = extractCount( s, "select count(*) from Order o where o.number = 1" );
assertEquals( "Order by id prop (virtual identifier)", 1, count ); assertEquals( 1, count, "Order by id prop (virtual identifier)" );
count = extractCount( s, "select count(*) from LineItem l where l.id = '456'" ); count = extractCount( s, "select count(*) from LineItem l where l.id = '456'" );
assertEquals( "LineItem by id prop (non-identifier", 1, count ); assertEquals( 1, count, "LineItem by id prop (non-identifier" );
if ( new DialectChecks.SupportsRowValueConstructorSyntaxCheck().isMatch( getDialect() ) ) { if ( new DialectFeatureChecks.SupportsRowValueConstructorSyntaxCheck().apply( scope.getSessionFactory()
.getJdbcServices()
.getDialect() ) ) {
Query q = s.createQuery( "select count(*) from LineItem l where l.pk = (:order, :product)" ) Query q = s.createQuery( "select count(*) from LineItem l where l.pk = (:order, :product)" )
.setParameter( "order", o ) .setParameter( "order", o )
.setParameter( "product", "my-product" ); .setParameter( "product", "my-product" );
count = extractCount( q ); count = extractCount( q );
assertEquals( "LineItem by pk prop (named composite identifier", 1, count ); assertEquals( 1, count, "LineItem by pk prop (named composite identifier" );
} }
count = extractCount( s, "select count(*) from Order o where o.orderee.id = 1" ); count = extractCount( s, "select count(*) from Order o where o.orderee.id = 1" );
@ -91,8 +107,4 @@ public class IdentifierPropertyReferencesTest extends BaseCoreFunctionalTestCase
return ( (Long) query.list().get( 0 ) ).longValue(); return ( (Long) query.list().get( 0 ) ).longValue();
} }
private long extractCount(Session s, CriteriaQuery crit) {
Query query = s.createQuery( crit );
return ( (Long) query.list().get( 0 ) ).longValue();
}
} }