HHH-7214 - Validation of duplicated discriminator values
This commit is contained in:
parent
51b9248c4b
commit
9fc22a49be
|
@ -410,7 +410,7 @@ public class SingleTableEntityPersister extends AbstractEntityPersister {
|
||||||
subclassClosure = new String[subclassSpan];
|
subclassClosure = new String[subclassSpan];
|
||||||
subclassClosure[0] = getEntityName();
|
subclassClosure[0] = getEntityName();
|
||||||
if ( persistentClass.isPolymorphic() ) {
|
if ( persistentClass.isPolymorphic() ) {
|
||||||
subclassesByDiscriminatorValue.put( discriminatorValue, getEntityName() );
|
addSubclassByDiscriminatorValue( discriminatorValue, getEntityName() );
|
||||||
}
|
}
|
||||||
|
|
||||||
// SUBCLASSES
|
// SUBCLASSES
|
||||||
|
@ -421,15 +421,15 @@ public class SingleTableEntityPersister extends AbstractEntityPersister {
|
||||||
Subclass sc = (Subclass) iter.next();
|
Subclass sc = (Subclass) iter.next();
|
||||||
subclassClosure[k++] = sc.getEntityName();
|
subclassClosure[k++] = sc.getEntityName();
|
||||||
if ( sc.isDiscriminatorValueNull() ) {
|
if ( sc.isDiscriminatorValueNull() ) {
|
||||||
subclassesByDiscriminatorValue.put( NULL_DISCRIMINATOR, sc.getEntityName() );
|
addSubclassByDiscriminatorValue( NULL_DISCRIMINATOR, sc.getEntityName() );
|
||||||
}
|
}
|
||||||
else if ( sc.isDiscriminatorValueNotNull() ) {
|
else if ( sc.isDiscriminatorValueNotNull() ) {
|
||||||
subclassesByDiscriminatorValue.put( NOT_NULL_DISCRIMINATOR, sc.getEntityName() );
|
addSubclassByDiscriminatorValue( NOT_NULL_DISCRIMINATOR, sc.getEntityName() );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
try {
|
try {
|
||||||
DiscriminatorType dtype = (DiscriminatorType) discriminatorType;
|
DiscriminatorType dtype = (DiscriminatorType) discriminatorType;
|
||||||
subclassesByDiscriminatorValue.put(
|
addSubclassByDiscriminatorValue(
|
||||||
dtype.stringToObject( sc.getDiscriminatorValue() ),
|
dtype.stringToObject( sc.getDiscriminatorValue() ),
|
||||||
sc.getEntityName()
|
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(
|
public SingleTableEntityPersister(
|
||||||
final EntityBinding entityBinding,
|
final EntityBinding entityBinding,
|
||||||
final EntityRegionAccessStrategy cacheAccessStrategy,
|
final EntityRegionAccessStrategy cacheAccessStrategy,
|
||||||
|
@ -674,7 +684,7 @@ public class SingleTableEntityPersister extends AbstractEntityPersister {
|
||||||
subclassClosure = new String[subclassSpan];
|
subclassClosure = new String[subclassSpan];
|
||||||
subclassClosure[0] = getEntityName();
|
subclassClosure[0] = getEntityName();
|
||||||
if ( entityBinding.isPolymorphic() ) {
|
if ( entityBinding.isPolymorphic() ) {
|
||||||
subclassesByDiscriminatorValue.put( discriminatorValue, getEntityName() );
|
addSubclassByDiscriminatorValue( discriminatorValue, getEntityName() );
|
||||||
}
|
}
|
||||||
|
|
||||||
// SUBCLASSES
|
// SUBCLASSES
|
||||||
|
@ -683,15 +693,15 @@ public class SingleTableEntityPersister extends AbstractEntityPersister {
|
||||||
for ( EntityBinding subEntityBinding : entityBinding.getPostOrderSubEntityBindingClosure() ) {
|
for ( EntityBinding subEntityBinding : entityBinding.getPostOrderSubEntityBindingClosure() ) {
|
||||||
subclassClosure[k++] = subEntityBinding.getEntity().getName();
|
subclassClosure[k++] = subEntityBinding.getEntity().getName();
|
||||||
if ( subEntityBinding.isDiscriminatorMatchValueNull() ) {
|
if ( subEntityBinding.isDiscriminatorMatchValueNull() ) {
|
||||||
subclassesByDiscriminatorValue.put( NULL_DISCRIMINATOR, subEntityBinding.getEntity().getName() );
|
addSubclassByDiscriminatorValue( NULL_DISCRIMINATOR, subEntityBinding.getEntity().getName() );
|
||||||
}
|
}
|
||||||
else if ( subEntityBinding.isDiscriminatorMatchValueNotNull() ) {
|
else if ( subEntityBinding.isDiscriminatorMatchValueNotNull() ) {
|
||||||
subclassesByDiscriminatorValue.put( NOT_NULL_DISCRIMINATOR, subEntityBinding.getEntity().getName() );
|
addSubclassByDiscriminatorValue( NOT_NULL_DISCRIMINATOR, subEntityBinding.getEntity().getName() );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
try {
|
try {
|
||||||
DiscriminatorType dtype = (DiscriminatorType) discriminatorType;
|
DiscriminatorType dtype = (DiscriminatorType) discriminatorType;
|
||||||
subclassesByDiscriminatorValue.put(
|
addSubclassByDiscriminatorValue(
|
||||||
dtype.stringToObject( subEntityBinding.getDiscriminatorMatchValue() ),
|
dtype.stringToObject( subEntityBinding.getDiscriminatorMatchValue() ),
|
||||||
subEntityBinding.getEntity().getName()
|
subEntityBinding.getEntity().getName()
|
||||||
);
|
);
|
||||||
|
|
|
@ -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 {
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue