HHH-6911 - Write DiscriminatorValue to DiscriminatorColumn when combined
with InheritanceType#JOINED Conflicts: hibernate-core/src/main/java/org/hibernate/cfg/AvailableSettings.java
This commit is contained in:
parent
b01abeadef
commit
d847a171eb
|
@ -829,7 +829,11 @@ public final class AnnotationBinder {
|
||||||
|
|
||||||
final DiscriminatorColumn discriminatorColumnAnnotation = clazzToProcess.getAnnotation( DiscriminatorColumn.class );
|
final DiscriminatorColumn discriminatorColumnAnnotation = clazzToProcess.getAnnotation( DiscriminatorColumn.class );
|
||||||
if ( !inheritanceState.hasParents() ) {
|
if ( !inheritanceState.hasParents() ) {
|
||||||
if ( discriminatorColumnAnnotation != null || mappings.useImplicitDiscriminatorColumnForJoinedInheritance() ) {
|
// we want to process the discriminator column if either:
|
||||||
|
// 1) There is an explicit DiscriminatorColumn annotation && we are not told to ignore them
|
||||||
|
// 2) There is not an explicit DiscriminatorColumn annotation && we are told to create them implicitly
|
||||||
|
if ( ( discriminatorColumnAnnotation != null && !mappings.ignoreExplicitDiscriminatorColumnForJoinedInheritance() )
|
||||||
|
|| ( discriminatorColumnAnnotation == null && mappings.useImplicitDiscriminatorColumnForJoinedInheritance() ) ) {
|
||||||
final DiscriminatorType discriminatorType = discriminatorColumnAnnotation != null
|
final DiscriminatorType discriminatorType = discriminatorColumnAnnotation != null
|
||||||
? discriminatorColumnAnnotation.discriminatorType()
|
? discriminatorColumnAnnotation.discriminatorType()
|
||||||
: DiscriminatorType.STRING;
|
: DiscriminatorType.STRING;
|
||||||
|
|
|
@ -617,11 +617,28 @@ public interface AvailableSettings {
|
||||||
* discriminator metadata means to follow the legacy behavior *unless* this setting is enabled. With this setting
|
* discriminator metadata means to follow the legacy behavior *unless* this setting is enabled. With this setting
|
||||||
* enabled, Hibernate will interpret the absence of discriminator metadata as an indication to use the JPA
|
* enabled, Hibernate will interpret the absence of discriminator metadata as an indication to use the JPA
|
||||||
* defined defaults for these absent annotations.
|
* defined defaults for these absent annotations.
|
||||||
|
* <p/>
|
||||||
|
* See Hibernate Jira issue HHH-6911 for additional background info.
|
||||||
*
|
*
|
||||||
* See Hibernate Jira issue HHH-6911 for additional background info,
|
* @see #IGNORE_EXPLICIT_DISCRIMINATOR_COLUMNS_FOR_JOINED_SUBCLASS
|
||||||
*/
|
*/
|
||||||
public static final String IMPLICIT_DISCRIMINATOR_COLUMNS_FOR_JOINED_SUBCLASS = "hibernate.discriminator.implicit_for_joined";
|
public static final String IMPLICIT_DISCRIMINATOR_COLUMNS_FOR_JOINED_SUBCLASS = "hibernate.discriminator.implicit_for_joined";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The legacy behavior of Hibernate is to not use discriminators for joined inheritance (Hibernate does not need
|
||||||
|
* the discriminator...). However, some JPA providers do need the discriminator for handling joined inheritance.
|
||||||
|
* In the interest of portability this capability has been added to Hibernate too.
|
||||||
|
* <p/>
|
||||||
|
* Existing applications rely (implicitly or explicitly) on Hibernate ignoring any DiscriminatorColumn declarations
|
||||||
|
* on joined inheritance hierarchies. This setting allows these applications to maintain the legacy behavior
|
||||||
|
* of DiscriminatorColumn annotations being ignored when paired with joined inheritance.
|
||||||
|
* <p/>
|
||||||
|
* See Hibernate Jira issue HHH-6911 for additional background info.
|
||||||
|
*
|
||||||
|
* @see #IMPLICIT_DISCRIMINATOR_COLUMNS_FOR_JOINED_SUBCLASS
|
||||||
|
*/
|
||||||
|
public static final String IGNORE_EXPLICIT_DISCRIMINATOR_COLUMNS_FOR_JOINED_SUBCLASS = "hibernate.discriminator.ignore_explicit_for_joined";
|
||||||
|
|
||||||
public static final String ENABLE_LAZY_LOAD_NO_TRANS = "hibernate.enable_lazy_load_no_trans";
|
public static final String ENABLE_LAZY_LOAD_NO_TRANS = "hibernate.enable_lazy_load_no_trans";
|
||||||
|
|
||||||
public static final String HQL_BULK_ID_STRATEGY = "hibernate.hql.bulk_id_strategy";
|
public static final String HQL_BULK_ID_STRATEGY = "hibernate.hql.bulk_id_strategy";
|
||||||
|
|
|
@ -3185,6 +3185,19 @@ public class Configuration implements Serializable {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private Boolean ignoreExplicitDiscriminatorColumnForJoinedInheritance;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean ignoreExplicitDiscriminatorColumnForJoinedInheritance() {
|
||||||
|
if ( ignoreExplicitDiscriminatorColumnForJoinedInheritance == null ) {
|
||||||
|
final String booleanName = getConfigurationProperties()
|
||||||
|
.getProperty( AvailableSettings.IGNORE_EXPLICIT_DISCRIMINATOR_COLUMNS_FOR_JOINED_SUBCLASS );
|
||||||
|
ignoreExplicitDiscriminatorColumnForJoinedInheritance = Boolean.valueOf( booleanName );
|
||||||
|
}
|
||||||
|
return ignoreExplicitDiscriminatorColumnForJoinedInheritance;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private Boolean useNationalizedCharacterData;
|
private Boolean useNationalizedCharacterData;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -748,16 +748,26 @@ public interface Mappings {
|
||||||
public boolean useNewGeneratorMappings();
|
public boolean useNewGeneratorMappings();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Should we handle discriminators for joined inheritance per legacy Hibernate rules, or
|
* Should we handle absent DiscriminatorColumn mappings for joined inheritance by implicitly mapping a
|
||||||
* Should we use the new generator strategy mappings. This is controlled by the
|
* discriminator column?
|
||||||
* {@link AvailableSettings#USE_NEW_ID_GENERATOR_MAPPINGS} setting.
|
|
||||||
*
|
*
|
||||||
* @return True if the new generators should be used, false otherwise.
|
* @return {@code true} indicates we should infer DiscriminatorColumn implicitly (aka, map to a discriminator
|
||||||
|
* column even without a DiscriminatorColumn annotation); {@code false} (the default) indicates that we should not.
|
||||||
*
|
*
|
||||||
* @see AvailableSettings#IMPLICIT_DISCRIMINATOR_COLUMNS_FOR_JOINED_SUBCLASS
|
* @see AvailableSettings#IMPLICIT_DISCRIMINATOR_COLUMNS_FOR_JOINED_SUBCLASS
|
||||||
*/
|
*/
|
||||||
public boolean useImplicitDiscriminatorColumnForJoinedInheritance();
|
public boolean useImplicitDiscriminatorColumnForJoinedInheritance();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Should we ignore explicit DiscriminatorColumn annotations when combined with joined inheritance?
|
||||||
|
*
|
||||||
|
* @return {@code true} indicates we should ignore explicit DiscriminatorColumn annotations; {@code false} (the
|
||||||
|
* default) indicates we should not ignore them
|
||||||
|
*
|
||||||
|
* @see AvailableSettings#IGNORE_EXPLICIT_DISCRIMINATOR_COLUMNS_FOR_JOINED_SUBCLASS
|
||||||
|
*/
|
||||||
|
public boolean ignoreExplicitDiscriminatorColumnForJoinedInheritance();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Should we use nationalized variants of character data by default? This is controlled by the
|
* Should we use nationalized variants of character data by default? This is controlled by the
|
||||||
* {@link AvailableSettings#USE_NATIONALIZED_CHARACTER_DATA} setting.
|
* {@link AvailableSettings#USE_NATIONALIZED_CHARACTER_DATA} setting.
|
||||||
|
|
|
@ -0,0 +1,122 @@
|
||||||
|
package org.hibernate.test.joinedsubclass;
|
||||||
|
|
||||||
|
import javax.persistence.DiscriminatorColumn;
|
||||||
|
import javax.persistence.DiscriminatorType;
|
||||||
|
import javax.persistence.DiscriminatorValue;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.Inheritance;
|
||||||
|
import javax.persistence.InheritanceType;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
|
||||||
|
import org.hibernate.Session;
|
||||||
|
import org.hibernate.cfg.AvailableSettings;
|
||||||
|
import org.hibernate.cfg.Configuration;
|
||||||
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
|
import org.hibernate.persister.entity.JoinedSubclassEntityPersister;
|
||||||
|
|
||||||
|
import org.hibernate.testing.TestForIssue;
|
||||||
|
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import static org.hibernate.testing.junit4.ExtraAssertions.assertTyping;
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertNotNull;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
@TestForIssue( jiraKey = "HHH-6911" )
|
||||||
|
public class JoinedSubclassWithIgnoredExplicitDiscriminatorTest extends BaseCoreFunctionalTestCase {
|
||||||
|
@Entity( name = "Animal" )
|
||||||
|
@Table( name = "animal" )
|
||||||
|
@Inheritance( strategy = InheritanceType.JOINED )
|
||||||
|
@DiscriminatorColumn( name = "type", discriminatorType = DiscriminatorType.STRING )
|
||||||
|
@DiscriminatorValue( value = "???animal???" )
|
||||||
|
public static abstract class Animal {
|
||||||
|
@Id
|
||||||
|
public Integer id;
|
||||||
|
|
||||||
|
protected Animal() {
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Animal(Integer id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Entity( name = "Cat" )
|
||||||
|
@DiscriminatorValue( value = "cat" )
|
||||||
|
public static class Cat extends Animal {
|
||||||
|
public Cat() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Cat(Integer id) {
|
||||||
|
super( id );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Entity( name = "Dog" )
|
||||||
|
@DiscriminatorValue( value = "dog" )
|
||||||
|
public static class Dog extends Animal {
|
||||||
|
public Dog() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Dog(Integer id) {
|
||||||
|
super( id );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Class<?>[] getAnnotatedClasses() {
|
||||||
|
return new Class[] { Animal.class, Cat.class, Dog.class };
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void configure(Configuration configuration) {
|
||||||
|
super.configure( configuration );
|
||||||
|
configuration.setProperty( AvailableSettings.IGNORE_EXPLICIT_DISCRIMINATOR_COLUMNS_FOR_JOINED_SUBCLASS, "true" );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void metadataAssertions() {
|
||||||
|
EntityPersister p = sessionFactory().getEntityPersister( Dog.class.getName() );
|
||||||
|
assertNotNull( p );
|
||||||
|
final JoinedSubclassEntityPersister dogPersister = assertTyping( JoinedSubclassEntityPersister.class, p );
|
||||||
|
assertEquals( "integer", dogPersister.getDiscriminatorType().getName() );
|
||||||
|
assertEquals( "clazz_", dogPersister.getDiscriminatorColumnName() );
|
||||||
|
assertTrue( Integer.class.isInstance( dogPersister.getDiscriminatorValue() ) );
|
||||||
|
|
||||||
|
p = sessionFactory().getEntityPersister( Cat.class.getName() );
|
||||||
|
assertNotNull( p );
|
||||||
|
final JoinedSubclassEntityPersister catPersister = assertTyping( JoinedSubclassEntityPersister.class, p );
|
||||||
|
assertEquals( "integer", catPersister.getDiscriminatorType().getName() );
|
||||||
|
assertEquals( "clazz_", catPersister.getDiscriminatorColumnName() );
|
||||||
|
assertTrue( Integer.class.isInstance( catPersister.getDiscriminatorValue() ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void basicUsageTest() {
|
||||||
|
Session session = openSession();
|
||||||
|
session.beginTransaction();
|
||||||
|
session.save( new Cat( 1 ) );
|
||||||
|
session.save( new Dog( 2 ) );
|
||||||
|
session.getTransaction().commit();
|
||||||
|
session.close();
|
||||||
|
|
||||||
|
session = openSession();
|
||||||
|
session.beginTransaction();
|
||||||
|
session.createQuery( "from Animal" ).list();
|
||||||
|
Cat cat = (Cat) session.get( Cat.class, 1 );
|
||||||
|
assertNotNull( cat );
|
||||||
|
session.delete( cat );
|
||||||
|
Dog dog = (Dog) session.get( Dog.class, 2 );
|
||||||
|
assertNotNull( dog );
|
||||||
|
session.delete( dog );
|
||||||
|
session.getTransaction().commit();
|
||||||
|
session.close();
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue