From 965e044850f26e06455ac1eaf1ec385684b811cc Mon Sep 17 00:00:00 2001 From: Gail Badner Date: Thu, 12 Mar 2015 23:40:47 -0700 Subject: [PATCH] HHH-9333 : TypeMismatchException when using composite-id and natural-id mappings --- .../entity/AbstractEntityPersister.java | 3 +- .../test/annotations/naturalid/cid/A.java | 54 ++++++++ .../test/annotations/naturalid/cid/AId.java | 64 ++++++++++ .../cid/EmbeddedAndNaturalIdTest.java | 116 +++++++++++++++++ .../test/naturalid/cid/Account.hbm.xml | 14 +++ .../hibernate/test/naturalid/cid/Account.java | 46 +++++++ .../test/naturalid/cid/AccountId.java | 60 +++++++++ .../cid/CompositeIdAndNaturalIdTest.java | 117 ++++++++++++++++++ 8 files changed, 473 insertions(+), 1 deletion(-) create mode 100644 hibernate-core/src/test/java/org/hibernate/test/annotations/naturalid/cid/A.java create mode 100644 hibernate-core/src/test/java/org/hibernate/test/annotations/naturalid/cid/AId.java create mode 100644 hibernate-core/src/test/java/org/hibernate/test/annotations/naturalid/cid/EmbeddedAndNaturalIdTest.java create mode 100644 hibernate-core/src/test/java/org/hibernate/test/naturalid/cid/Account.hbm.xml create mode 100644 hibernate-core/src/test/java/org/hibernate/test/naturalid/cid/Account.java create mode 100644 hibernate-core/src/test/java/org/hibernate/test/naturalid/cid/AccountId.java create mode 100644 hibernate-core/src/test/java/org/hibernate/test/naturalid/cid/CompositeIdAndNaturalIdTest.java diff --git a/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java b/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java index 39e8a6015f..cab8016d3f 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java @@ -4641,7 +4641,8 @@ public abstract class AbstractEntityPersister return null; } - return (Serializable) getIdentifierType().hydrate( rs, getIdentifierAliases(), session, null ); + final Object hydratedId = getIdentifierType().hydrate( rs, getIdentifierAliases(), session, null ); + return (Serializable) getIdentifierType().resolve( hydratedId, session, null ); } finally { session.getTransactionCoordinator().getJdbcCoordinator().release( rs, ps ); diff --git a/hibernate-core/src/test/java/org/hibernate/test/annotations/naturalid/cid/A.java b/hibernate-core/src/test/java/org/hibernate/test/annotations/naturalid/cid/A.java new file mode 100644 index 0000000000..d232da2e06 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/test/annotations/naturalid/cid/A.java @@ -0,0 +1,54 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2015, Red Hat Inc. or third-party contributors as + * indicated by the @author tags or express copyright attribution + * statements applied by the authors. All third-party contributions are + * distributed under license by Red Hat Inc. + * + * This copyrighted material is made available to anyone wishing to use, modify, + * copy, or redistribute it subject to the terms and conditions of the GNU + * Lesser General Public License, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this distribution; if not, write to: + * Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301 USA + */ +package org.hibernate.test.annotations.naturalid.cid; + +import javax.persistence.EmbeddedId; +import javax.persistence.Entity; + +import org.hibernate.annotations.NaturalId; + +/** + * @author Donnchadh O Donnabhain + */ +@Entity +public class A { + @EmbeddedId + private AId accountId; + @NaturalId(mutable = false) + private String shortCode; + + protected A() { + } + + public A(AId accountId, String shortCode) { + this.accountId = accountId; + this.shortCode = shortCode; + } + public String getShortCode() { + return shortCode; + } + public AId getAccountId() { + return accountId; + } +} diff --git a/hibernate-core/src/test/java/org/hibernate/test/annotations/naturalid/cid/AId.java b/hibernate-core/src/test/java/org/hibernate/test/annotations/naturalid/cid/AId.java new file mode 100644 index 0000000000..ea172fb98b --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/test/annotations/naturalid/cid/AId.java @@ -0,0 +1,64 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2015, Red Hat Inc. or third-party contributors as + * indicated by the @author tags or express copyright attribution + * statements applied by the authors. All third-party contributions are + * distributed under license by Red Hat Inc. + * + * This copyrighted material is made available to anyone wishing to use, modify, + * copy, or redistribute it subject to the terms and conditions of the GNU + * Lesser General Public License, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this distribution; if not, write to: + * Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301 USA + */ +package org.hibernate.test.annotations.naturalid.cid; + +import javax.persistence.Embeddable; + +/** + * @author Donnchadh O Donnabhain + */ + +@Embeddable +public class AId implements java.io.Serializable { + private final int id; + + protected AId() { + this.id = 0; + } + + public AId(int id) { + this.id = id; + } + public int intValue() { + return id; + } + @Override + public int hashCode() { + return id; + } + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + AId other = (AId) obj; + if (other != null && id != other.id) + return false; + return true; + } +} + diff --git a/hibernate-core/src/test/java/org/hibernate/test/annotations/naturalid/cid/EmbeddedAndNaturalIdTest.java b/hibernate-core/src/test/java/org/hibernate/test/annotations/naturalid/cid/EmbeddedAndNaturalIdTest.java new file mode 100644 index 0000000000..b32f0cf12b --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/test/annotations/naturalid/cid/EmbeddedAndNaturalIdTest.java @@ -0,0 +1,116 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2015, Red Hat Inc. or third-party contributors as + * indicated by the @author tags or express copyright attribution + * statements applied by the authors. All third-party contributions are + * distributed under license by Red Hat Inc. + * + * This copyrighted material is made available to anyone wishing to use, modify, + * copy, or redistribute it subject to the terms and conditions of the GNU + * Lesser General Public License, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this distribution; if not, write to: + * Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301 USA + */ +package org.hibernate.test.annotations.naturalid.cid; + +import static org.junit.Assert.assertNotNull; + +import org.hibernate.Session; +import org.hibernate.criterion.Restrictions; +import org.hibernate.testing.TestForIssue; +import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; +import org.junit.Test; + +/** + * @author Donnchadh O Donnabhain + */ +@SuppressWarnings("unchecked") +public class EmbeddedAndNaturalIdTest extends BaseCoreFunctionalTestCase { + @TestForIssue(jiraKey = "HHH-9333") + @Test + public void testSave() { + // prepare some test data... + Session session = openSession(); + session.beginTransaction(); + A account = new A(new AId(1), "testCode"); + session.save( account ); + session.getTransaction().commit(); + session.close(); + + // clean up + session = openSession(); + session.beginTransaction(); + session.delete( account ); + session.getTransaction().commit(); + session.close(); + } + + @TestForIssue(jiraKey = "HHH-9333") + @Test + public void testNaturalIdCriteria() { + Session s = openSession(); + s.beginTransaction(); + A u = new A(new AId(1), "testCode" ); + s.persist( u ); + s.getTransaction().commit(); + s.close(); + + s = openSession(); + s.beginTransaction(); + u = ( A ) s.createCriteria( A.class ) + .add( Restrictions.naturalId().set( "shortCode", "testCode" ) ) + .uniqueResult(); + assertNotNull( u ); + s.getTransaction().commit(); + s.close(); + + s = openSession(); + s.beginTransaction(); + s.createQuery( "delete A" ).executeUpdate(); + s.getTransaction().commit(); + s.close(); + } + + @TestForIssue(jiraKey = "HHH-9333") + @Test + public void testByNaturalId() { + Session s = openSession(); + s.beginTransaction(); + A u = new A(new AId(1), "testCode" ); + s.persist( u ); + s.getTransaction().commit(); + s.close(); + + s = openSession(); + s.beginTransaction(); + u = ( A ) s.byNaturalId(A.class).using("shortCode", "testCode").load(); + assertNotNull( u ); + s.getTransaction().commit(); + s.close(); + + s = openSession(); + s.beginTransaction(); + s.createQuery( "delete A" ).executeUpdate(); + s.getTransaction().commit(); + s.close(); + } + + @Override + protected Class[] getAnnotatedClasses() { + return new Class[] { + A.class, + AId.class + }; + } + +} diff --git a/hibernate-core/src/test/java/org/hibernate/test/naturalid/cid/Account.hbm.xml b/hibernate-core/src/test/java/org/hibernate/test/naturalid/cid/Account.hbm.xml new file mode 100644 index 0000000000..858690ff37 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/test/naturalid/cid/Account.hbm.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/hibernate-core/src/test/java/org/hibernate/test/naturalid/cid/Account.java b/hibernate-core/src/test/java/org/hibernate/test/naturalid/cid/Account.java new file mode 100644 index 0000000000..5b7aa25e61 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/test/naturalid/cid/Account.java @@ -0,0 +1,46 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2015, Red Hat Inc. or third-party contributors as + * indicated by the @author tags or express copyright attribution + * statements applied by the authors. All third-party contributions are + * distributed under license by Red Hat Inc. + * + * This copyrighted material is made available to anyone wishing to use, modify, + * copy, or redistribute it subject to the terms and conditions of the GNU + * Lesser General Public License, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this distribution; if not, write to: + * Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301 USA + */ +package org.hibernate.test.naturalid.cid; + +/** + * @author Donnchadh O Donnabhain + */ +public class Account { + private AccountId accountId; + private String shortCode; + + protected Account() { + } + + public Account(AccountId accountId, String shortCode) { + this.accountId = accountId; + this.shortCode = shortCode; + } + public String getShortCode() { + return shortCode; + } + public AccountId getAccountId() { + return accountId; + } +} diff --git a/hibernate-core/src/test/java/org/hibernate/test/naturalid/cid/AccountId.java b/hibernate-core/src/test/java/org/hibernate/test/naturalid/cid/AccountId.java new file mode 100644 index 0000000000..69f33337cf --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/test/naturalid/cid/AccountId.java @@ -0,0 +1,60 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2015, Red Hat Inc. or third-party contributors as + * indicated by the @author tags or express copyright attribution + * statements applied by the authors. All third-party contributions are + * distributed under license by Red Hat Inc. + * + * This copyrighted material is made available to anyone wishing to use, modify, + * copy, or redistribute it subject to the terms and conditions of the GNU + * Lesser General Public License, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this distribution; if not, write to: + * Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301 USA + */ +package org.hibernate.test.naturalid.cid; + +/** + * @author Donnchadh O Donnabhain + */ +public class AccountId implements java.io.Serializable { + private final int id; + + protected AccountId() { + this.id = 0; + } + + public AccountId(int id) { + this.id = id; + } + public int intValue() { + return id; + } + @Override + public int hashCode() { + return id; + } + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + AccountId other = (AccountId) obj; + if (other != null && id != other.id) + return false; + return true; + } +} + diff --git a/hibernate-core/src/test/java/org/hibernate/test/naturalid/cid/CompositeIdAndNaturalIdTest.java b/hibernate-core/src/test/java/org/hibernate/test/naturalid/cid/CompositeIdAndNaturalIdTest.java new file mode 100644 index 0000000000..fa76a04e6b --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/test/naturalid/cid/CompositeIdAndNaturalIdTest.java @@ -0,0 +1,117 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2015, Red Hat Inc. or third-party contributors as + * indicated by the @author tags or express copyright attribution + * statements applied by the authors. All third-party contributions are + * distributed under license by Red Hat Inc. + * + * This copyrighted material is made available to anyone wishing to use, modify, + * copy, or redistribute it subject to the terms and conditions of the GNU + * Lesser General Public License, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this distribution; if not, write to: + * Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301 USA + */ +package org.hibernate.test.naturalid.cid; + +import static org.junit.Assert.assertNotNull; + +import org.hibernate.Session; +import org.hibernate.cfg.Configuration; +import org.hibernate.cfg.Environment; +import org.hibernate.criterion.Restrictions; +import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; +import org.junit.Test; + +/** + * @author Donnchadh O Donnabhain + */ +public class CompositeIdAndNaturalIdTest extends BaseCoreFunctionalTestCase { + + public String[] getMappings() { + return new String[] { "naturalid/cid/Account.hbm.xml" }; + } + + public void configure(Configuration cfg) { + cfg.setProperty( Environment.USE_SECOND_LEVEL_CACHE, "false" ); + cfg.setProperty( Environment.USE_QUERY_CACHE, "false" ); + cfg.setProperty( Environment.GENERATE_STATISTICS, "false" ); + } + + @Test + public void testSave() { + // prepare some test data... + Session session = openSession(); + session.beginTransaction(); + Account account = new Account(new AccountId(1), "testAcct"); + session.save( account ); + session.getTransaction().commit(); + session.close(); + + // clean up + session = openSession(); + session.beginTransaction(); + session.delete( account ); + session.getTransaction().commit(); + session.close(); + } + + @Test + public void testNaturalIdCriteria() { + Session s = openSession(); + s.beginTransaction(); + Account u = new Account(new AccountId(1), "testAcct" ); + s.persist( u ); + s.getTransaction().commit(); + s.close(); + + s = openSession(); + s.beginTransaction(); + u = ( Account ) s.createCriteria( Account.class ) + .add( Restrictions.naturalId().set( "shortCode", "testAcct" ) ) + .setCacheable( true ) + .uniqueResult(); + assertNotNull( u ); + s.getTransaction().commit(); + s.close(); + + s = openSession(); + s.beginTransaction(); + s.createQuery( "delete Account" ).executeUpdate(); + s.getTransaction().commit(); + s.close(); + } + + @Test + public void testByNaturalId() { + Session s = openSession(); + s.beginTransaction(); + Account u = new Account(new AccountId(1), "testAcct" ); + s.persist( u ); + s.getTransaction().commit(); + s.close(); + + s = openSession(); + s.beginTransaction(); + u = ( Account ) s.byNaturalId(Account.class).using("shortCode", "testAcct").load(); + assertNotNull( u ); + s.getTransaction().commit(); + s.close(); + + s = openSession(); + s.beginTransaction(); + s.createQuery( "delete Account" ).executeUpdate(); + s.getTransaction().commit(); + s.close(); + } + +}