From 982aad716f2f06d9c0390768610075b1dc6af08a Mon Sep 17 00:00:00 2001 From: Steve Ebersole Date: Wed, 29 Feb 2012 15:32:54 -0600 Subject: [PATCH] HHH-7129 - Throw exception when metadata attempts to spread @NaturalId across an entity hierarchy --- .../cfg/annotations/EntityBinder.java | 5 ++ .../cfg/annotations/PropertyBinder.java | 3 + .../inheritance/spread/Principal.java | 72 +++++++++++++++++++ .../spread/SpreadNaturalIdTest.java | 53 ++++++++++++++ .../naturalid/inheritance/spread/User.java | 57 +++++++++++++++ 5 files changed, 190 insertions(+) create mode 100644 hibernate-core/src/matrix/java/org/hibernate/test/naturalid/inheritance/spread/Principal.java create mode 100644 hibernate-core/src/matrix/java/org/hibernate/test/naturalid/inheritance/spread/SpreadNaturalIdTest.java create mode 100644 hibernate-core/src/matrix/java/org/hibernate/test/naturalid/inheritance/spread/User.java diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/annotations/EntityBinder.java b/hibernate-core/src/main/java/org/hibernate/cfg/annotations/EntityBinder.java index fa06ed925d..2d59c61fec 100644 --- a/hibernate-core/src/main/java/org/hibernate/cfg/annotations/EntityBinder.java +++ b/hibernate-core/src/main/java/org/hibernate/cfg/annotations/EntityBinder.java @@ -183,6 +183,11 @@ public class EntityBinder { } } + public boolean isRootEntity() { + // This is the best option I can think of here since PersistentClass is most likely not yet fully populated + return persistentClass instanceof RootClass; + } + public void setDiscriminatorValue(String discriminatorValue) { this.discriminatorValue = discriminatorValue; } diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/annotations/PropertyBinder.java b/hibernate-core/src/main/java/org/hibernate/cfg/annotations/PropertyBinder.java index 7969766e06..81893e58b1 100644 --- a/hibernate-core/src/main/java/org/hibernate/cfg/annotations/PropertyBinder.java +++ b/hibernate-core/src/main/java/org/hibernate/cfg/annotations/PropertyBinder.java @@ -285,6 +285,9 @@ public class PropertyBinder { } NaturalId naturalId = property != null ? property.getAnnotation( NaturalId.class ) : null; if ( naturalId != null ) { + if ( ! entityBinder.isRootEntity() ) { + throw new AnnotationException( "@NaturalId only valid on root entity (or its @MappedSuperclasses)" ); + } if ( ! naturalId.mutable() ) { updatable = false; } diff --git a/hibernate-core/src/matrix/java/org/hibernate/test/naturalid/inheritance/spread/Principal.java b/hibernate-core/src/matrix/java/org/hibernate/test/naturalid/inheritance/spread/Principal.java new file mode 100644 index 0000000000..5667681c53 --- /dev/null +++ b/hibernate-core/src/matrix/java/org/hibernate/test/naturalid/inheritance/spread/Principal.java @@ -0,0 +1,72 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2012, 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.inheritance.spread; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.Inheritance; +import javax.persistence.InheritanceType; +import javax.persistence.Table; + +import org.hibernate.annotations.GenericGenerator; +import org.hibernate.annotations.NaturalId; + +/** + * @author Steve Ebersole + */ +@Entity +@Inheritance( strategy = InheritanceType.JOINED ) +@Table( name = "GK_PRINCIPAL" ) +public abstract class Principal { + private Long id; + private String uid; + + protected Principal() { + } + + protected Principal(String uid) { + this.uid = uid; + } + + @Id + @GeneratedValue( generator = "increment" ) + @GenericGenerator( name = "increment", strategy = "increment" ) + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + @NaturalId + public String getUid() { + return uid; + } + + public void setUid(String uid) { + this.uid = uid; + } +} diff --git a/hibernate-core/src/matrix/java/org/hibernate/test/naturalid/inheritance/spread/SpreadNaturalIdTest.java b/hibernate-core/src/matrix/java/org/hibernate/test/naturalid/inheritance/spread/SpreadNaturalIdTest.java new file mode 100644 index 0000000000..8aa14864c0 --- /dev/null +++ b/hibernate-core/src/matrix/java/org/hibernate/test/naturalid/inheritance/spread/SpreadNaturalIdTest.java @@ -0,0 +1,53 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2012, 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.inheritance.spread; + +import org.hibernate.AnnotationException; +import org.hibernate.cfg.Configuration; + +import org.junit.Test; + +import org.hibernate.testing.TestForIssue; +import org.hibernate.testing.junit4.BaseUnitTestCase; + +import static org.junit.Assert.fail; + +/** + * @author Steve Ebersole + */ +@TestForIssue( jiraKey = "HHH-7129" ) +public class SpreadNaturalIdTest extends BaseUnitTestCase { + @Test + public void testSpreadNaturalIdDeclarationGivesMappingException() { + Configuration cfg = new Configuration() + .addAnnotatedClass( Principal.class ) + .addAnnotatedClass( User.class ); + try { + cfg.buildMappings(); + fail( "Expected binders to throw an exception" ); + } + catch (AnnotationException expected) { + } + } +} diff --git a/hibernate-core/src/matrix/java/org/hibernate/test/naturalid/inheritance/spread/User.java b/hibernate-core/src/matrix/java/org/hibernate/test/naturalid/inheritance/spread/User.java new file mode 100644 index 0000000000..3997f9896c --- /dev/null +++ b/hibernate-core/src/matrix/java/org/hibernate/test/naturalid/inheritance/spread/User.java @@ -0,0 +1,57 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2012, 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.inheritance.spread; + +import javax.persistence.Entity; +import javax.persistence.Table; + +import org.hibernate.annotations.NaturalId; + +/** + * @author Steve Ebersole + */ +@Entity +@Table( name = "GK_USER" ) +public class User extends Principal { + private String userName; + + public User() { + } + + public User(String uid) { + super( uid ); + // stupid, but this is just to test the "spreading" declaration of natural id, not whether these particular + // values make sense :) + this.userName = uid; + } + + @NaturalId + public String getUserName() { + return userName; + } + + public void setUserName(String userName) { + this.userName = userName; + } +}