HHH-7214 - Validation of duplicated discriminator values

This commit is contained in:
Lukasz Antoniak 2013-04-18 11:10:08 +02:00 committed by Brett Meyer
parent 51b9248c4b
commit 9fc22a49be
2 changed files with 109 additions and 8 deletions

View File

@ -410,7 +410,7 @@ public class SingleTableEntityPersister extends AbstractEntityPersister {
subclassClosure = new String[subclassSpan];
subclassClosure[0] = getEntityName();
if ( persistentClass.isPolymorphic() ) {
subclassesByDiscriminatorValue.put( discriminatorValue, getEntityName() );
addSubclassByDiscriminatorValue( discriminatorValue, getEntityName() );
}
// SUBCLASSES
@ -421,15 +421,15 @@ public class SingleTableEntityPersister extends AbstractEntityPersister {
Subclass sc = (Subclass) iter.next();
subclassClosure[k++] = sc.getEntityName();
if ( sc.isDiscriminatorValueNull() ) {
subclassesByDiscriminatorValue.put( NULL_DISCRIMINATOR, sc.getEntityName() );
addSubclassByDiscriminatorValue( NULL_DISCRIMINATOR, sc.getEntityName() );
}
else if ( sc.isDiscriminatorValueNotNull() ) {
subclassesByDiscriminatorValue.put( NOT_NULL_DISCRIMINATOR, sc.getEntityName() );
addSubclassByDiscriminatorValue( NOT_NULL_DISCRIMINATOR, sc.getEntityName() );
}
else {
try {
DiscriminatorType dtype = (DiscriminatorType) discriminatorType;
subclassesByDiscriminatorValue.put(
addSubclassByDiscriminatorValue(
dtype.stringToObject( sc.getDiscriminatorValue() ),
sc.getEntityName()
);
@ -452,6 +452,16 @@ public class SingleTableEntityPersister extends AbstractEntityPersister {
}
private void addSubclassByDiscriminatorValue(Object discriminatorValue, String entityName) {
String mappedEntityName = (String) subclassesByDiscriminatorValue.put( discriminatorValue, entityName );
if ( mappedEntityName != null ) {
throw new MappingException(
"Entities [" + entityName + "] and [" + mappedEntityName
+ "] are mapped with the same discriminator value '" + discriminatorValue + "'."
);
}
}
public SingleTableEntityPersister(
final EntityBinding entityBinding,
final EntityRegionAccessStrategy cacheAccessStrategy,
@ -674,7 +684,7 @@ public class SingleTableEntityPersister extends AbstractEntityPersister {
subclassClosure = new String[subclassSpan];
subclassClosure[0] = getEntityName();
if ( entityBinding.isPolymorphic() ) {
subclassesByDiscriminatorValue.put( discriminatorValue, getEntityName() );
addSubclassByDiscriminatorValue( discriminatorValue, getEntityName() );
}
// SUBCLASSES
@ -683,15 +693,15 @@ public class SingleTableEntityPersister extends AbstractEntityPersister {
for ( EntityBinding subEntityBinding : entityBinding.getPostOrderSubEntityBindingClosure() ) {
subclassClosure[k++] = subEntityBinding.getEntity().getName();
if ( subEntityBinding.isDiscriminatorMatchValueNull() ) {
subclassesByDiscriminatorValue.put( NULL_DISCRIMINATOR, subEntityBinding.getEntity().getName() );
addSubclassByDiscriminatorValue( NULL_DISCRIMINATOR, subEntityBinding.getEntity().getName() );
}
else if ( subEntityBinding.isDiscriminatorMatchValueNotNull() ) {
subclassesByDiscriminatorValue.put( NOT_NULL_DISCRIMINATOR, subEntityBinding.getEntity().getName() );
addSubclassByDiscriminatorValue( NOT_NULL_DISCRIMINATOR, subEntityBinding.getEntity().getName() );
}
else {
try {
DiscriminatorType dtype = (DiscriminatorType) discriminatorType;
subclassesByDiscriminatorValue.put(
addSubclassByDiscriminatorValue(
dtype.stringToObject( subEntityBinding.getDiscriminatorMatchValue() ),
subEntityBinding.getEntity().getName()
);

View File

@ -0,0 +1,91 @@
package org.hibernate.test.annotations.inheritance.singletable;
import javax.persistence.DiscriminatorColumn;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import org.junit.Assert;
import org.junit.Test;
import org.hibernate.MappingException;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.testing.ServiceRegistryBuilder;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.junit4.BaseUnitTestCase;
/**
* @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com)
*/
@TestForIssue( jiraKey = "HHH-7214" )
public class DuplicatedDiscriminatorValueTest extends BaseUnitTestCase {
private static final String DISCRIMINATOR_VALUE = "D";
@Test
public void testDuplicatedDiscriminatorValueSameHierarchy() {
try {
tryBuildingSessionFactory( Building.class, Building1.class, Building2.class );
Assert.fail( MappingException.class.getName() + " expected when two subclasses are mapped with the same discriminator value." );
}
catch ( MappingException e ) {
final String errorMsg = e.getCause().getMessage();
// Check if error message contains descriptive information.
Assert.assertTrue( errorMsg.contains( Building1.class.getName() ) );
Assert.assertTrue( errorMsg.contains( Building2.class.getName() ) );
Assert.assertTrue( errorMsg.contains( "discriminator value '" + DISCRIMINATOR_VALUE + "'." ) );
}
}
@Test
public void testDuplicatedDiscriminatorValueDifferentHierarchy() {
tryBuildingSessionFactory( Building.class, Building1.class, Furniture.class, Chair.class );
}
private void tryBuildingSessionFactory(Class... annotatedClasses) {
Configuration cfg = new Configuration();
for ( Class annotatedClass : annotatedClasses ) {
cfg.addAnnotatedClass( annotatedClass );
}
ServiceRegistry serviceRegistry = null;
SessionFactory sessionFactory = null;
try {
serviceRegistry = ServiceRegistryBuilder.buildServiceRegistry( cfg.getProperties() );
sessionFactory = cfg.buildSessionFactory( serviceRegistry );
}
finally {
if ( sessionFactory != null ) {
sessionFactory.close();
}
if ( serviceRegistry != null ) {
ServiceRegistryBuilder.destroy( serviceRegistry );
}
}
}
@Entity
@DiscriminatorValue(DISCRIMINATOR_VALUE) // Duplicated discriminator value in single hierarchy.
private static class Building1 extends Building {
}
@Entity
@DiscriminatorValue(DISCRIMINATOR_VALUE) // Duplicated discriminator value in single hierarchy.
private static class Building2 extends Building {
}
@Entity
@DiscriminatorColumn(name = "entity_type")
@DiscriminatorValue("F")
private static class Furniture {
@Id
@GeneratedValue
private Integer id;
}
@Entity
@DiscriminatorValue(DISCRIMINATOR_VALUE) // Duplicated discriminator value in different hierarchy.
private static class Chair extends Furniture {
}
}