HHH-18172 Validate exclusivity of annotated class types

This commit is contained in:
Marco Belladelli 2024-05-28 16:41:49 +02:00
parent 9aaebe312a
commit 4ed529c289
2 changed files with 102 additions and 1 deletions

View File

@ -20,6 +20,7 @@ import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;
import org.hibernate.AnnotationException;
import org.hibernate.AssertionFailure;
import org.hibernate.DuplicateMappingException;
import org.hibernate.HibernateException;
@ -1271,9 +1272,18 @@ public class InFlightMetadataCollectorImpl implements InFlightMetadataCollector,
private static AnnotatedClassType getAnnotatedClassType(XClass clazz) {
if ( clazz.isAnnotationPresent( Entity.class ) ) {
if ( clazz.isAnnotationPresent( Embeddable.class ) ) {
throw new AnnotationException( "Invalid class annotated both '@Entity' and '@Embeddable': '" + clazz.getName() + "'" );
}
else if ( clazz.isAnnotationPresent( jakarta.persistence.MappedSuperclass.class ) ) {
throw new AnnotationException( "Invalid class annotated both '@Entity' and '@MappedSuperclass': '" + clazz.getName() + "'" );
}
return AnnotatedClassType.ENTITY;
}
else if ( clazz.isAnnotationPresent( Embeddable.class ) ) {
if ( clazz.isAnnotationPresent( jakarta.persistence.MappedSuperclass.class ) ) {
throw new AnnotationException( "Invalid class annotated both '@Embeddable' and '@MappedSuperclass': '" + clazz.getName() + "'" );
}
return AnnotatedClassType.EMBEDDABLE;
}
else if ( clazz.isAnnotationPresent( jakarta.persistence.MappedSuperclass.class ) ) {
@ -1287,7 +1297,6 @@ public class InFlightMetadataCollectorImpl implements InFlightMetadataCollector,
}
}
@Override
public void addMappedSuperclass(Class<?> type, MappedSuperclass mappedSuperclass) {
if ( mappedSuperClasses == null ) {

View File

@ -0,0 +1,92 @@
/*
* 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.annotations;
import org.hibernate.cfg.Configuration;
import org.hibernate.testing.ServiceRegistryBuilder;
import org.hibernate.testing.orm.junit.Jira;
import org.junit.jupiter.api.Test;
import jakarta.persistence.Embeddable;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.MappedSuperclass;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.fail;
/**
* @author Marco Belladelli
*/
@Jira( "https://hibernate.atlassian.net/browse/HHH-18172" )
public class InvalidAnnotatedClassTypesTest {
@Test
public void testEntityAndEmbeddable() {
try {
Configuration config = new Configuration();
config.addAnnotatedClass( EntityAndEmbeddable.class );
config.buildSessionFactory( ServiceRegistryBuilder.buildServiceRegistry() );
fail( "Classes annotated with multiple types should not be allowed" );
}
catch (Exception e) {
assertThat( e ).isNotNull();
}
}
@Test
public void testMappedSuperclassAndEntity() {
try {
Configuration config = new Configuration();
config.addAnnotatedClass( MappedSuperclassAndEntity.class );
config.addAnnotatedClass( ExtendingEntity.class );
config.buildSessionFactory( ServiceRegistryBuilder.buildServiceRegistry() );
fail( "Classes annotated with multiple types should not be allowed" );
}
catch (Exception e) {
assertThat( e ).isNotNull();
}
}
@Test
public void testEmbeddableAndMappedSuperclass() {
try {
Configuration config = new Configuration();
config.addAnnotatedClass( EmbeddableAndMappedSuperclass.class );
config.addAnnotatedClass( ExtendingEmbeddable.class );
config.buildSessionFactory( ServiceRegistryBuilder.buildServiceRegistry() );
fail( "Classes annotated with multiple types should not be allowed" );
}
catch (Exception e) {
assertThat( e ).isNotNull();
}
}
@Entity
@Embeddable
static class EntityAndEmbeddable {
@Id
private Long id;
}
@MappedSuperclass
@Entity
static class MappedSuperclassAndEntity {
@Id
private Long id;
}
static class ExtendingEntity extends MappedSuperclassAndEntity {
}
@Embeddable
@MappedSuperclass
static class EmbeddableAndMappedSuperclass {
}
static class ExtendingEmbeddable extends EmbeddableAndMappedSuperclass {}
}