mirror of
https://github.com/hibernate/hibernate-orm
synced 2025-02-08 20:24:46 +00:00
Merge remote-tracking branch 'upstream/master' into wip/6.0
This commit is contained in:
commit
731cbbc739
@ -904,6 +904,9 @@ If enabled, allows schema update and validation to support synonyms. Due to the
|
|||||||
`*hibernate.hbm2ddl.extra_physical_table_types*` (e.g. `BASE TABLE`)::
|
`*hibernate.hbm2ddl.extra_physical_table_types*` (e.g. `BASE TABLE`)::
|
||||||
Identifies a comma-separated list of values to specify extra table types, other than the default `TABLE` value, to recognize as defining a physical table by schema update, creation and validation.
|
Identifies a comma-separated list of values to specify extra table types, other than the default `TABLE` value, to recognize as defining a physical table by schema update, creation and validation.
|
||||||
|
|
||||||
|
`*hibernate.hbm2ddl.default_constraint_mode*` (`CONSTRAINT` (default value) or `NO_CONSTRAINT`)::
|
||||||
|
Default `javax.persistence.ConstraintMode` for foreign key mapping if `PROVIDER_DEFAULT` strategy used.
|
||||||
|
|
||||||
`*hibernate.schema_update.unique_constraint_strategy*` (e.g. `DROP_RECREATE_QUIETLY`, `RECREATE_QUIETLY`, `SKIP`)::
|
`*hibernate.schema_update.unique_constraint_strategy*` (e.g. `DROP_RECREATE_QUIETLY`, `RECREATE_QUIETLY`, `SKIP`)::
|
||||||
Unique columns and unique keys both use unique constraints in most dialects.
|
Unique columns and unique keys both use unique constraints in most dialects.
|
||||||
`SchemaUpdate` needs to create these constraints, but DBs support for finding existing constraints is extremely inconsistent.
|
`SchemaUpdate` needs to create these constraints, but DBs support for finding existing constraints is extremely inconsistent.
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.Callable;
|
import java.util.concurrent.Callable;
|
||||||
import javax.persistence.AttributeConverter;
|
import javax.persistence.AttributeConverter;
|
||||||
|
import javax.persistence.ConstraintMode;
|
||||||
import javax.persistence.SharedCacheMode;
|
import javax.persistence.SharedCacheMode;
|
||||||
|
|
||||||
import org.hibernate.HibernateException;
|
import org.hibernate.HibernateException;
|
||||||
@ -314,6 +315,11 @@ public MetadataBuilder allowSpecjSyntax() {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public MetadataBuilder noConstraintByDefault() {
|
||||||
|
this.options.noConstraintByDefault = true;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MetadataBuilder applySqlFunction(String functionName, SqmFunctionDescriptor function) {
|
public MetadataBuilder applySqlFunction(String functionName, SqmFunctionDescriptor function) {
|
||||||
this.bootstrapContext.addSqlFunction( functionName, function );
|
this.bootstrapContext.addSqlFunction( functionName, function );
|
||||||
@ -542,6 +548,7 @@ public static class MetadataBuildingOptionsImpl
|
|||||||
private boolean implicitlyForceDiscriminatorInSelect;
|
private boolean implicitlyForceDiscriminatorInSelect;
|
||||||
private boolean useNationalizedCharacterData;
|
private boolean useNationalizedCharacterData;
|
||||||
private boolean specjProprietarySyntaxEnabled;
|
private boolean specjProprietarySyntaxEnabled;
|
||||||
|
private boolean noConstraintByDefault;
|
||||||
private ArrayList<MetadataSourceType> sourceProcessOrdering;
|
private ArrayList<MetadataSourceType> sourceProcessOrdering;
|
||||||
|
|
||||||
private IdGeneratorInterpreterImpl idGenerationTypeInterpreter = new IdGeneratorInterpreterImpl();
|
private IdGeneratorInterpreterImpl idGenerationTypeInterpreter = new IdGeneratorInterpreterImpl();
|
||||||
@ -634,6 +641,12 @@ public AccessType convert(Object value) {
|
|||||||
false
|
false
|
||||||
);
|
);
|
||||||
|
|
||||||
|
this.noConstraintByDefault = ConstraintMode.NO_CONSTRAINT.name().equalsIgnoreCase( configService.getSetting(
|
||||||
|
AvailableSettings.HBM2DDL_DEFAULT_CONSTRAINT_MODE,
|
||||||
|
String.class,
|
||||||
|
null
|
||||||
|
) );
|
||||||
|
|
||||||
this.implicitNamingStrategy = strategySelector.resolveDefaultableStrategy(
|
this.implicitNamingStrategy = strategySelector.resolveDefaultableStrategy(
|
||||||
ImplicitNamingStrategy.class,
|
ImplicitNamingStrategy.class,
|
||||||
configService.getSettings().get( AvailableSettings.IMPLICIT_NAMING_STRATEGY ),
|
configService.getSettings().get( AvailableSettings.IMPLICIT_NAMING_STRATEGY ),
|
||||||
@ -814,6 +827,11 @@ public boolean isSpecjProprietarySyntaxEnabled() {
|
|||||||
return specjProprietarySyntaxEnabled;
|
return specjProprietarySyntaxEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isNoConstraintByDefault() {
|
||||||
|
return noConstraintByDefault;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<MetadataSourceType> getSourceProcessOrdering() {
|
public List<MetadataSourceType> getSourceProcessOrdering() {
|
||||||
return sourceProcessOrdering;
|
return sourceProcessOrdering;
|
||||||
|
@ -154,6 +154,11 @@ public boolean isSpecjProprietarySyntaxEnabled() {
|
|||||||
return delegate.isSpecjProprietarySyntaxEnabled();
|
return delegate.isSpecjProprietarySyntaxEnabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isNoConstraintByDefault() {
|
||||||
|
return delegate.isNoConstraintByDefault();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<MetadataSourceType> getSourceProcessOrdering() {
|
public List<MetadataSourceType> getSourceProcessOrdering() {
|
||||||
return delegate.getSourceProcessOrdering();
|
return delegate.getSourceProcessOrdering();
|
||||||
|
@ -239,6 +239,16 @@ default CollectionSemanticsResolver getPersistentCollectionRepresentationResolve
|
|||||||
|
|
||||||
boolean isSpecjProprietarySyntaxEnabled();
|
boolean isSpecjProprietarySyntaxEnabled();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Should we create constraint by default?
|
||||||
|
*
|
||||||
|
* @see javax.persistence.ConstraintMode#PROVIDER_DEFAULT
|
||||||
|
* @see org.hibernate.cfg.AvailableSettings#DEFAULT_CONSTRAINT_MODE
|
||||||
|
*
|
||||||
|
* @return {@code true} if not create constraint by default; {@code false} otherwise.
|
||||||
|
*/
|
||||||
|
boolean isNoConstraintByDefault();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve the ordering in which sources should be processed.
|
* Retrieve the ordering in which sources should be processed.
|
||||||
*
|
*
|
||||||
|
@ -150,6 +150,8 @@
|
|||||||
import org.hibernate.cfg.annotations.QueryBinder;
|
import org.hibernate.cfg.annotations.QueryBinder;
|
||||||
import org.hibernate.cfg.annotations.TableBinder;
|
import org.hibernate.cfg.annotations.TableBinder;
|
||||||
import org.hibernate.engine.OptimisticLockStyle;
|
import org.hibernate.engine.OptimisticLockStyle;
|
||||||
|
import org.hibernate.engine.config.spi.ConfigurationService;
|
||||||
|
import org.hibernate.engine.config.spi.StandardConverters;
|
||||||
import org.hibernate.engine.spi.FilterDefinition;
|
import org.hibernate.engine.spi.FilterDefinition;
|
||||||
import org.hibernate.id.PersistentIdentifierGenerator;
|
import org.hibernate.id.PersistentIdentifierGenerator;
|
||||||
import org.hibernate.internal.CoreMessageLogger;
|
import org.hibernate.internal.CoreMessageLogger;
|
||||||
@ -739,15 +741,17 @@ else if ( InheritanceType.JOINED.equals( inheritanceState.getType() ) ) {
|
|||||||
else {
|
else {
|
||||||
final PrimaryKeyJoinColumn pkJoinColumn = clazzToProcess.getAnnotation( PrimaryKeyJoinColumn.class );
|
final PrimaryKeyJoinColumn pkJoinColumn = clazzToProcess.getAnnotation( PrimaryKeyJoinColumn.class );
|
||||||
final PrimaryKeyJoinColumns pkJoinColumns = clazzToProcess.getAnnotation( PrimaryKeyJoinColumns.class );
|
final PrimaryKeyJoinColumns pkJoinColumns = clazzToProcess.getAnnotation( PrimaryKeyJoinColumns.class );
|
||||||
|
final boolean noConstraintByDefault = context.getBuildingOptions().isNoConstraintByDefault();
|
||||||
if ( pkJoinColumns != null && pkJoinColumns.foreignKey().value() == ConstraintMode.NO_CONSTRAINT ) {
|
if ( pkJoinColumns != null && ( pkJoinColumns.foreignKey().value() == ConstraintMode.NO_CONSTRAINT
|
||||||
|
|| pkJoinColumns.foreignKey().value() == ConstraintMode.PROVIDER_DEFAULT && noConstraintByDefault ) ) {
|
||||||
// don't apply a constraint based on ConstraintMode
|
// don't apply a constraint based on ConstraintMode
|
||||||
key.setForeignKeyName( "none" );
|
key.setForeignKeyName( "none" );
|
||||||
}
|
}
|
||||||
else if ( pkJoinColumns != null && !StringHelper.isEmpty( pkJoinColumns.foreignKey().name() ) ) {
|
else if ( pkJoinColumns != null && !StringHelper.isEmpty( pkJoinColumns.foreignKey().name() ) ) {
|
||||||
key.setForeignKeyName( pkJoinColumns.foreignKey().name() );
|
key.setForeignKeyName( pkJoinColumns.foreignKey().name() );
|
||||||
}
|
}
|
||||||
else if ( pkJoinColumn != null && pkJoinColumn.foreignKey().value() == ConstraintMode.NO_CONSTRAINT ) {
|
else if ( pkJoinColumn != null && ( pkJoinColumn.foreignKey().value() == ConstraintMode.NO_CONSTRAINT
|
||||||
|
|| pkJoinColumn.foreignKey().value() == ConstraintMode.PROVIDER_DEFAULT && noConstraintByDefault )) {
|
||||||
// don't apply a constraint based on ConstraintMode
|
// don't apply a constraint based on ConstraintMode
|
||||||
key.setForeignKeyName( "none" );
|
key.setForeignKeyName( "none" );
|
||||||
}
|
}
|
||||||
@ -3178,7 +3182,8 @@ private static void bindManyToOne(
|
|||||||
property,
|
property,
|
||||||
propertyHolder.getOverriddenForeignKey( StringHelper.qualify( propertyHolder.getPath(), propertyName ) ),
|
propertyHolder.getOverriddenForeignKey( StringHelper.qualify( propertyHolder.getPath(), propertyName ) ),
|
||||||
joinColumn,
|
joinColumn,
|
||||||
joinColumns
|
joinColumns,
|
||||||
|
context
|
||||||
);
|
);
|
||||||
|
|
||||||
String path = propertyHolder.getPath() + "." + propertyName;
|
String path = propertyHolder.getPath() + "." + propertyName;
|
||||||
@ -3524,9 +3529,13 @@ public static void bindForeignKeyNameAndDefinition(
|
|||||||
XProperty property,
|
XProperty property,
|
||||||
javax.persistence.ForeignKey fkOverride,
|
javax.persistence.ForeignKey fkOverride,
|
||||||
JoinColumn joinColumn,
|
JoinColumn joinColumn,
|
||||||
JoinColumns joinColumns) {
|
JoinColumns joinColumns,
|
||||||
if ( ( joinColumn != null && joinColumn.foreignKey().value() == ConstraintMode.NO_CONSTRAINT )
|
MetadataBuildingContext context) {
|
||||||
|| ( joinColumns != null && joinColumns.foreignKey().value() == ConstraintMode.NO_CONSTRAINT ) ) {
|
final boolean noConstraintByDefault = context.getBuildingOptions().isNoConstraintByDefault();
|
||||||
|
if ( ( joinColumn != null && ( joinColumn.foreignKey().value() == ConstraintMode.NO_CONSTRAINT
|
||||||
|
|| joinColumn.foreignKey().value() == ConstraintMode.PROVIDER_DEFAULT && noConstraintByDefault ) )
|
||||||
|
|| ( joinColumns != null && ( joinColumns.foreignKey().value() == ConstraintMode.NO_CONSTRAINT
|
||||||
|
|| joinColumns.foreignKey().value() == ConstraintMode.PROVIDER_DEFAULT && noConstraintByDefault ) ) ) {
|
||||||
value.setForeignKeyName( "none" );
|
value.setForeignKeyName( "none" );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -3535,7 +3544,8 @@ public static void bindForeignKeyNameAndDefinition(
|
|||||||
value.setForeignKeyName( fk.name() );
|
value.setForeignKeyName( fk.name() );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if ( fkOverride != null && fkOverride.value() == ConstraintMode.NO_CONSTRAINT ) {
|
if ( fkOverride != null && ( fkOverride.value() == ConstraintMode.NO_CONSTRAINT
|
||||||
|
|| fkOverride.value() == ConstraintMode.PROVIDER_DEFAULT && noConstraintByDefault ) ) {
|
||||||
value.setForeignKeyName( "none" );
|
value.setForeignKeyName( "none" );
|
||||||
}
|
}
|
||||||
else if ( fkOverride != null ) {
|
else if ( fkOverride != null ) {
|
||||||
|
@ -1600,6 +1600,19 @@ public interface AvailableSettings extends org.hibernate.jpa.AvailableSettings {
|
|||||||
*/
|
*/
|
||||||
String HBM2DDL_HALT_ON_ERROR = "hibernate.hbm2ddl.halt_on_error";
|
String HBM2DDL_HALT_ON_ERROR = "hibernate.hbm2ddl.halt_on_error";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* This setting is used when you use {@link javax.persistence.ConstraintMode#PROVIDER_DEFAULT} strategy for foreign key mapping.
|
||||||
|
* valid value is {@code CONSTRAINT} and {@code NO_CONSTRAINT}.
|
||||||
|
* </p>
|
||||||
|
* <p>
|
||||||
|
* The default value is CONSTRAINT.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @since 5.4
|
||||||
|
*/
|
||||||
|
String HBM2DDL_DEFAULT_CONSTRAINT_MODE = "hibernate.hbm2ddl.default_constraint_mode";
|
||||||
|
|
||||||
String JMX_ENABLED = "hibernate.jmx.enabled";
|
String JMX_ENABLED = "hibernate.jmx.enabled";
|
||||||
String JMX_PLATFORM_SERVER = "hibernate.jmx.usePlatformServer";
|
String JMX_PLATFORM_SERVER = "hibernate.jmx.usePlatformServer";
|
||||||
String JMX_AGENT_ID = "hibernate.jmx.agentId";
|
String JMX_AGENT_ID = "hibernate.jmx.agentId";
|
||||||
|
@ -103,7 +103,8 @@ public void doSecondPass(Map persistentClasses) throws MappingException {
|
|||||||
inferredData.getProperty(),
|
inferredData.getProperty(),
|
||||||
inferredData.getProperty().getAnnotation( javax.persistence.ForeignKey.class ),
|
inferredData.getProperty().getAnnotation( javax.persistence.ForeignKey.class ),
|
||||||
inferredData.getProperty().getAnnotation( JoinColumn.class ),
|
inferredData.getProperty().getAnnotation( JoinColumn.class ),
|
||||||
inferredData.getProperty().getAnnotation( JoinColumns.class )
|
inferredData.getProperty().getAnnotation( JoinColumns.class),
|
||||||
|
buildingContext
|
||||||
);
|
);
|
||||||
|
|
||||||
PropertyBinder binder = new PropertyBinder();
|
PropertyBinder binder = new PropertyBinder();
|
||||||
@ -276,7 +277,8 @@ else if ( otherSideProperty.getValue() instanceof ManyToOne ) {
|
|||||||
* Note:<br/>
|
* Note:<br/>
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>From the mappedBy side we should not create the PK nor the FK, this is handled from the other side.</li>
|
* <li>From the mappedBy side we should not create the PK nor the FK, this is handled from the other side.</li>
|
||||||
* <li>This method is a dirty dupe of EntityBinder.bindSecondaryTable</i>.
|
* <li>This method is a dirty dupe of EntityBinder.bindSecondaryTable</li>.
|
||||||
|
* </ul>
|
||||||
* </p>
|
* </p>
|
||||||
*/
|
*/
|
||||||
private Join buildJoinFromMappedBySide(PersistentClass persistentClass, Property otherSideProperty, Join originalJoin) {
|
private Join buildJoinFromMappedBySide(PersistentClass persistentClass, Property otherSideProperty, Join originalJoin) {
|
||||||
|
@ -1162,6 +1162,7 @@ private static SimpleValue buildCollectionKey(
|
|||||||
Collection collValue,
|
Collection collValue,
|
||||||
Ejb3JoinColumn[] joinColumns,
|
Ejb3JoinColumn[] joinColumns,
|
||||||
boolean cascadeDeleteEnabled,
|
boolean cascadeDeleteEnabled,
|
||||||
|
boolean noConstraintByDefault,
|
||||||
XProperty property,
|
XProperty property,
|
||||||
PropertyHolder propertyHolder,
|
PropertyHolder propertyHolder,
|
||||||
MetadataBuildingContext buildingContext) {
|
MetadataBuildingContext buildingContext) {
|
||||||
@ -1206,7 +1207,8 @@ private static SimpleValue buildCollectionKey(
|
|||||||
else {
|
else {
|
||||||
final CollectionTable collectionTableAnn = property.getAnnotation( CollectionTable.class );
|
final CollectionTable collectionTableAnn = property.getAnnotation( CollectionTable.class );
|
||||||
if ( collectionTableAnn != null ) {
|
if ( collectionTableAnn != null ) {
|
||||||
if ( collectionTableAnn.foreignKey().value() == ConstraintMode.NO_CONSTRAINT ) {
|
if ( collectionTableAnn.foreignKey().value() == ConstraintMode.NO_CONSTRAINT
|
||||||
|
|| collectionTableAnn.foreignKey().value() == ConstraintMode.PROVIDER_DEFAULT && noConstraintByDefault ) {
|
||||||
key.setForeignKeyName( "none" );
|
key.setForeignKeyName( "none" );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -1237,7 +1239,8 @@ private static SimpleValue buildCollectionKey(
|
|||||||
foreignKeyValue = joinColumnAnn.foreignKey().value();
|
foreignKeyValue = joinColumnAnn.foreignKey().value();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ( foreignKeyValue == ConstraintMode.NO_CONSTRAINT ) {
|
if ( foreignKeyValue == ConstraintMode.NO_CONSTRAINT
|
||||||
|
|| foreignKeyValue == ConstraintMode.PROVIDER_DEFAULT && noConstraintByDefault ) {
|
||||||
key.setForeignKeyName( "none" );
|
key.setForeignKeyName( "none" );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -1249,7 +1252,8 @@ private static SimpleValue buildCollectionKey(
|
|||||||
final javax.persistence.ForeignKey fkOverride = propertyHolder.getOverriddenForeignKey(
|
final javax.persistence.ForeignKey fkOverride = propertyHolder.getOverriddenForeignKey(
|
||||||
StringHelper.qualify( propertyHolder.getPath(), property.getName() )
|
StringHelper.qualify( propertyHolder.getPath(), property.getName() )
|
||||||
);
|
);
|
||||||
if ( fkOverride != null && fkOverride.value() == ConstraintMode.NO_CONSTRAINT ) {
|
if ( fkOverride != null && ( fkOverride.value() == ConstraintMode.NO_CONSTRAINT ||
|
||||||
|
fkOverride.value() == ConstraintMode.PROVIDER_DEFAULT && noConstraintByDefault ) ) {
|
||||||
key.setForeignKeyName( "none" );
|
key.setForeignKeyName( "none" );
|
||||||
}
|
}
|
||||||
else if ( fkOverride != null ) {
|
else if ( fkOverride != null ) {
|
||||||
@ -1259,7 +1263,8 @@ else if ( fkOverride != null ) {
|
|||||||
else {
|
else {
|
||||||
final JoinColumn joinColumnAnn = property.getAnnotation( JoinColumn.class );
|
final JoinColumn joinColumnAnn = property.getAnnotation( JoinColumn.class );
|
||||||
if ( joinColumnAnn != null ) {
|
if ( joinColumnAnn != null ) {
|
||||||
if ( joinColumnAnn.foreignKey().value() == ConstraintMode.NO_CONSTRAINT ) {
|
if ( joinColumnAnn.foreignKey().value() == ConstraintMode.NO_CONSTRAINT
|
||||||
|
|| joinColumnAnn.foreignKey().value() == ConstraintMode.PROVIDER_DEFAULT && noConstraintByDefault ) {
|
||||||
key.setForeignKeyName( "none" );
|
key.setForeignKeyName( "none" );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -1455,7 +1460,8 @@ else if ( anyAnn != null ) {
|
|||||||
foreignKeyValue = joinColumnAnn.foreignKey().value();
|
foreignKeyValue = joinColumnAnn.foreignKey().value();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ( joinTableAnn.inverseForeignKey().value() == ConstraintMode.NO_CONSTRAINT ) {
|
if ( joinTableAnn.inverseForeignKey().value() == ConstraintMode.NO_CONSTRAINT
|
||||||
|
|| joinTableAnn.inverseForeignKey().value() == ConstraintMode.PROVIDER_DEFAULT && buildingContext.getBuildingOptions().isNoConstraintByDefault() ) {
|
||||||
element.setForeignKeyName( "none" );
|
element.setForeignKeyName( "none" );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -1689,7 +1695,8 @@ private static void bindCollectionSecondPass(
|
|||||||
catch (AnnotationException ex) {
|
catch (AnnotationException ex) {
|
||||||
throw new AnnotationException( "Unable to map collection " + collValue.getOwner().getClassName() + "." + property.getName(), ex );
|
throw new AnnotationException( "Unable to map collection " + collValue.getOwner().getClassName() + "." + property.getName(), ex );
|
||||||
}
|
}
|
||||||
SimpleValue key = buildCollectionKey( collValue, joinColumns, cascadeDeleteEnabled, property, propertyHolder, buildingContext );
|
SimpleValue key = buildCollectionKey( collValue, joinColumns, cascadeDeleteEnabled,
|
||||||
|
buildingContext.getBuildingOptions().isNoConstraintByDefault(), property, propertyHolder, buildingContext );
|
||||||
if ( property.isAnnotationPresent( ElementCollection.class ) && joinColumns.length > 0 ) {
|
if ( property.isAnnotationPresent( ElementCollection.class ) && joinColumns.length > 0 ) {
|
||||||
joinColumns[0].setJPA2ElementCollection( true );
|
joinColumns[0].setJPA2ElementCollection( true );
|
||||||
}
|
}
|
||||||
|
@ -985,7 +985,9 @@ private void setFKNameIfDefined(Join join) {
|
|||||||
else {
|
else {
|
||||||
javax.persistence.SecondaryTable jpaSecondaryTable = findMatchingSecondaryTable( join );
|
javax.persistence.SecondaryTable jpaSecondaryTable = findMatchingSecondaryTable( join );
|
||||||
if ( jpaSecondaryTable != null ) {
|
if ( jpaSecondaryTable != null ) {
|
||||||
if ( jpaSecondaryTable.foreignKey().value() == ConstraintMode.NO_CONSTRAINT ) {
|
final boolean noConstraintByDefault = context.getBuildingOptions().isNoConstraintByDefault();
|
||||||
|
if ( jpaSecondaryTable.foreignKey().value() == ConstraintMode.NO_CONSTRAINT
|
||||||
|
|| jpaSecondaryTable.foreignKey().value() == ConstraintMode.PROVIDER_DEFAULT && noConstraintByDefault ) {
|
||||||
( (SimpleValue) join.getKey() ).setForeignKeyName( "none" );
|
( (SimpleValue) join.getKey() ).setForeignKeyName( "none" );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -347,7 +347,8 @@ else if ( owner.getIdentifierMapper() != null && owner.getIdentifierMapper().get
|
|||||||
if ( element != null ) {
|
if ( element != null ) {
|
||||||
final javax.persistence.ForeignKey foreignKey = getMapKeyForeignKey( property );
|
final javax.persistence.ForeignKey foreignKey = getMapKeyForeignKey( property );
|
||||||
if ( foreignKey != null ) {
|
if ( foreignKey != null ) {
|
||||||
if ( foreignKey.value() == ConstraintMode.NO_CONSTRAINT ) {
|
if ( foreignKey.value() == ConstraintMode.NO_CONSTRAINT
|
||||||
|
|| foreignKey.value() == ConstraintMode.PROVIDER_DEFAULT && getBuildingContext().getBuildingOptions().isNoConstraintByDefault() ) {
|
||||||
element.setForeignKeyName( "none" );
|
element.setForeignKeyName( "none" );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -26,7 +26,7 @@ public interface RootGraph<J> extends Graph<J>, EntityGraph<J> {
|
|||||||
|
|
||||||
boolean appliesTo(String entityName);
|
boolean appliesTo(String entityName);
|
||||||
|
|
||||||
boolean appliesTo(Class<? super J> entityType);
|
boolean appliesTo(Class entityType);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
RootGraph<J> makeRootGraph(String name, boolean mutable);
|
RootGraph<J> makeRootGraph(String name, boolean mutable);
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
import org.hibernate.metamodel.model.domain.EntityDomainType;
|
import org.hibernate.metamodel.model.domain.EntityDomainType;
|
||||||
import org.hibernate.metamodel.model.domain.IdentifiableDomainType;
|
import org.hibernate.metamodel.model.domain.IdentifiableDomainType;
|
||||||
import org.hibernate.metamodel.model.domain.JpaMetamodel;
|
import org.hibernate.metamodel.model.domain.JpaMetamodel;
|
||||||
|
import org.hibernate.metamodel.model.domain.ManagedDomainType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Hibernate implementation of the JPA EntityGraph contract.
|
* The Hibernate implementation of the JPA EntityGraph contract.
|
||||||
@ -79,13 +80,14 @@ public <T1> SubGraph<? extends T1> addSubclassSubgraph(Class<? extends T1> type)
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean appliesTo(EntityDomainType<? super J> entityType) {
|
public boolean appliesTo(EntityDomainType<? super J> entityType) {
|
||||||
if ( this.getGraphedType().equals( entityType ) ) {
|
final ManagedDomainType<J> managedTypeDescriptor = getGraphedType();
|
||||||
|
if ( managedTypeDescriptor.equals( entityType ) ) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
IdentifiableDomainType superType = entityType.getSupertype();
|
IdentifiableDomainType<? super J> superType = entityType.getSupertype();
|
||||||
while ( superType != null ) {
|
while ( superType != null ) {
|
||||||
if ( superType.equals( entityType ) ) {
|
if ( managedTypeDescriptor.equals( superType ) ) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
superType = superType.getSupertype();
|
superType = superType.getSupertype();
|
||||||
@ -100,7 +102,7 @@ public boolean appliesTo(String entityName) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean appliesTo(Class<? super J> type) {
|
public boolean appliesTo(Class type) {
|
||||||
return appliesTo( jpaMetamodel().entity( type ) );
|
return appliesTo( jpaMetamodel().entity( type ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -111,10 +111,12 @@ public PrimaryKey getPrimaryKey() {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Iterator getUniqueKeyIterator() {
|
public Iterator getUniqueKeyIterator() {
|
||||||
Iterator iter = includedTable.getUniqueKeyIterator();
|
if ( !includedTable.isPhysicalTable() ) {
|
||||||
while ( iter.hasNext() ) {
|
Iterator iter = includedTable.getUniqueKeyIterator();
|
||||||
UniqueKey uk = (UniqueKey) iter.next();
|
while ( iter.hasNext() ) {
|
||||||
createUniqueKey( uk.getColumns() );
|
UniqueKey uk = (UniqueKey) iter.next();
|
||||||
|
createUniqueKey( uk.getColumns() );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return getUniqueKeys().values().iterator();
|
return getUniqueKeys().values().iterator();
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,105 @@
|
|||||||
|
/*
|
||||||
|
* 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.graph;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import javax.persistence.AttributeNode;
|
||||||
|
import javax.persistence.EntityGraph;
|
||||||
|
import javax.persistence.EntityManager;
|
||||||
|
import javax.persistence.Subgraph;
|
||||||
|
|
||||||
|
import org.hibernate.graph.spi.RootGraphImplementor;
|
||||||
|
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
|
||||||
|
|
||||||
|
import org.junit.Assert;
|
||||||
|
|
||||||
|
public abstract class AbstractEntityGraphTest extends BaseEntityManagerFunctionalTestCase {
|
||||||
|
|
||||||
|
public AbstractEntityGraphTest() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Class<?>[] getAnnotatedClasses() {
|
||||||
|
return new Class[]{ GraphParsingTestEntity.class, GraphParsingTestSubentity.class };
|
||||||
|
}
|
||||||
|
|
||||||
|
protected <T> RootGraphImplementor<T> parseGraph(Class<T> entityType, String graphString) {
|
||||||
|
EntityManager entityManager = getOrCreateEntityManager();
|
||||||
|
return (RootGraphImplementor<T>) GraphParser.parse( entityType, graphString, entityManager );
|
||||||
|
}
|
||||||
|
|
||||||
|
protected <T> RootGraphImplementor<GraphParsingTestEntity> parseGraph(String graphString) {
|
||||||
|
return parseGraph( GraphParsingTestEntity.class, graphString );
|
||||||
|
}
|
||||||
|
|
||||||
|
private <C extends Collection<?>> void assertNullOrEmpty(C collection) {
|
||||||
|
if ( collection != null ) {
|
||||||
|
Assert.assertEquals( 0, collection.size() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected <M extends Map<?, ?>> void assertNullOrEmpty(M map) {
|
||||||
|
if ( map != null ) {
|
||||||
|
Assert.assertEquals( 0, map.size() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void assertBasicAttributes(EntityGraph<?> graph, String... names) {
|
||||||
|
Assert.assertNotNull( graph );
|
||||||
|
assertBasicAttributes( graph.getAttributeNodes(), names );
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void assertBasicAttributes(Subgraph<?> graph, String... names) {
|
||||||
|
Assert.assertNotNull( graph );
|
||||||
|
assertBasicAttributes( graph.getAttributeNodes(), names );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assertBasicAttributes(List<AttributeNode<?>> attrs, String... names) {
|
||||||
|
if ( ( names == null ) || ( names.length == 0 ) ) {
|
||||||
|
assertNullOrEmpty( attrs );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Assert.assertNotNull( attrs );
|
||||||
|
Assert.assertTrue( names.length <= attrs.size() );
|
||||||
|
|
||||||
|
for ( String name : names ) {
|
||||||
|
AttributeNode<?> node = null;
|
||||||
|
for ( AttributeNode<?> candidate : attrs ) {
|
||||||
|
if ( candidate.getAttributeName().equals( name ) ) {
|
||||||
|
node = candidate;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Assert.assertNotNull( node );
|
||||||
|
assertNullOrEmpty( node.getKeySubgraphs() );
|
||||||
|
assertNullOrEmpty( node.getSubgraphs() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected AttributeNode<?> getAttributeNodeByName(EntityGraph<?> graph, String name, boolean required) {
|
||||||
|
return getAttributeNodeByName( graph.getAttributeNodes(), name, required );
|
||||||
|
}
|
||||||
|
|
||||||
|
protected AttributeNode<?> getAttributeNodeByName(Subgraph<?> graph, String name, boolean required) {
|
||||||
|
return getAttributeNodeByName( graph.getAttributeNodes(), name, required );
|
||||||
|
}
|
||||||
|
|
||||||
|
private AttributeNode<?> getAttributeNodeByName(List<AttributeNode<?>> attrs, String name, boolean required) {
|
||||||
|
for ( AttributeNode<?> attr : attrs ) {
|
||||||
|
if ( name.equals( attr.getAttributeName() ) )
|
||||||
|
return attr;
|
||||||
|
}
|
||||||
|
if ( required )
|
||||||
|
Assert.fail( "Required attribute not found." );
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,202 @@
|
|||||||
|
/*
|
||||||
|
* 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.graph;
|
||||||
|
|
||||||
|
import javax.persistence.EntityGraph;
|
||||||
|
import javax.persistence.EntityManager;
|
||||||
|
|
||||||
|
import org.hibernate.graph.spi.RootGraphImplementor;
|
||||||
|
|
||||||
|
import org.hibernate.testing.TestForIssue;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Ignore;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class EntityGraphsTest extends AbstractEntityGraphTest {
|
||||||
|
|
||||||
|
private final <T> void checkMerge(Class<T> rootType, EntityGraph<T> expected, @SuppressWarnings("unchecked") EntityGraph<T>... graphs) {
|
||||||
|
EntityManager entityManager = getOrCreateEntityManager();
|
||||||
|
EntityGraph<T> actual = EntityGraphs.merge( entityManager, rootType, graphs );
|
||||||
|
Assert.assertTrue( EntityGraphs.areEqual( expected, actual ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
@SafeVarargs
|
||||||
|
private final void checkMerge(EntityGraph<GraphParsingTestEntity> expected, EntityGraph<GraphParsingTestEntity>... graphs) {
|
||||||
|
checkMerge( GraphParsingTestEntity.class, expected, graphs );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSameBasicsEqual() {
|
||||||
|
EntityGraph<GraphParsingTestEntity> g = parseGraph( "name, description " );
|
||||||
|
Assert.assertTrue( EntityGraphs.areEqual( g, g ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEqualBasicsEqual() {
|
||||||
|
EntityGraph<GraphParsingTestEntity> a = parseGraph( "name, description " );
|
||||||
|
EntityGraph<GraphParsingTestEntity> b = parseGraph( "description, name " );
|
||||||
|
Assert.assertTrue( EntityGraphs.areEqual( a, b ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDifferentBasicsEqual1() {
|
||||||
|
EntityGraph<GraphParsingTestEntity> a = parseGraph( "name, description " );
|
||||||
|
EntityGraph<GraphParsingTestEntity> b = parseGraph( "description " );
|
||||||
|
Assert.assertFalse( EntityGraphs.areEqual( a, b ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDifferentBasicsEqual2() {
|
||||||
|
EntityGraph<GraphParsingTestEntity> a = parseGraph( "name " );
|
||||||
|
EntityGraph<GraphParsingTestEntity> b = parseGraph( "description " );
|
||||||
|
Assert.assertFalse( EntityGraphs.areEqual( a, b ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEqualLinksEqual1() {
|
||||||
|
EntityGraph<GraphParsingTestEntity> a = parseGraph( "linkToOne(name, description)" );
|
||||||
|
EntityGraph<GraphParsingTestEntity> b = parseGraph( "linkToOne(description, name)" );
|
||||||
|
Assert.assertTrue( EntityGraphs.areEqual( a, b ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Ignore("Cannot run due to Hibernate bug: https://hibernate.atlassian.net/browse/HHH-10378")
|
||||||
|
public void testEqualLinksWithSubclassesEqual() {
|
||||||
|
EntityGraph<GraphParsingTestEntity> a = parseGraph( "linkToOne(name), linkToOne:MockSubentity(description)" );
|
||||||
|
EntityGraph<GraphParsingTestEntity> b = parseGraph( "linkToOne:MockSubentity(description), linkToOne(name)" );
|
||||||
|
Assert.assertTrue( EntityGraphs.areEqual( a, b ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDifferentLinksEqual1() {
|
||||||
|
EntityGraph<GraphParsingTestEntity> a = parseGraph( "linkToOne(name, description)" );
|
||||||
|
EntityGraph<GraphParsingTestEntity> b = parseGraph( "linkToOne(description)" );
|
||||||
|
Assert.assertFalse( EntityGraphs.areEqual( a, b ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDifferentLinksEqual2() {
|
||||||
|
EntityGraph<GraphParsingTestEntity> a = parseGraph( "linkToOne(name)" );
|
||||||
|
EntityGraph<GraphParsingTestEntity> b = parseGraph( "linkToOne(description)" );
|
||||||
|
Assert.assertFalse( EntityGraphs.areEqual( a, b ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Ignore("Cannot run due to Hibernate bug: https://hibernate.atlassian.net/browse/HHH-10378")
|
||||||
|
public void testDifferentLinksEqual3() {
|
||||||
|
EntityGraph<GraphParsingTestEntity> a = parseGraph( "linkToOne(name), linkToOne:MockSubentity(description)" );
|
||||||
|
EntityGraph<GraphParsingTestEntity> b = parseGraph( "linkToOne(name, description)" );
|
||||||
|
Assert.assertFalse( EntityGraphs.areEqual( a, b ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEqualMapKeysEqual() {
|
||||||
|
EntityGraph<GraphParsingTestEntity> a = parseGraph( "map.key(name, description)" );
|
||||||
|
EntityGraph<GraphParsingTestEntity> b = parseGraph( "map.key(description, name)" );
|
||||||
|
Assert.assertTrue( EntityGraphs.areEqual( a, b ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDifferentMapKeysEqual1() {
|
||||||
|
EntityGraph<GraphParsingTestEntity> a = parseGraph( "map.key(name, description)" );
|
||||||
|
EntityGraph<GraphParsingTestEntity> b = parseGraph( "map.key(description)" );
|
||||||
|
Assert.assertFalse( EntityGraphs.areEqual( a, b ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDifferentMapKeysEqual2() {
|
||||||
|
EntityGraph<GraphParsingTestEntity> a = parseGraph( "map.key(name)" );
|
||||||
|
EntityGraph<GraphParsingTestEntity> b = parseGraph( "map.key(description)" );
|
||||||
|
Assert.assertFalse( EntityGraphs.areEqual( a, b ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEqualMapValuesEqual() {
|
||||||
|
EntityGraph<GraphParsingTestEntity> a = parseGraph( "map.value(name, description)" );
|
||||||
|
EntityGraph<GraphParsingTestEntity> b = parseGraph( "map.value(description, name)" );
|
||||||
|
Assert.assertTrue( EntityGraphs.areEqual( a, b ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDifferentMapValuesEqual1() {
|
||||||
|
EntityGraph<GraphParsingTestEntity> a = parseGraph( "map.value(name, description)" );
|
||||||
|
EntityGraph<GraphParsingTestEntity> b = parseGraph( "map.value(description)" );
|
||||||
|
Assert.assertFalse( EntityGraphs.areEqual( a, b ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDifferentMapValuesEqual2() {
|
||||||
|
EntityGraph<GraphParsingTestEntity> a = parseGraph( "map.value(name)" );
|
||||||
|
EntityGraph<GraphParsingTestEntity> b = parseGraph( "map.value(description)" );
|
||||||
|
Assert.assertFalse( EntityGraphs.areEqual( a, b ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEqualComplexGraphsEqual() {
|
||||||
|
EntityGraph<GraphParsingTestEntity> a = parseGraph( "map.key(name, description), name, linkToOne(description), description" );
|
||||||
|
EntityGraph<GraphParsingTestEntity> b = parseGraph( "description, map.key(description, name), name, linkToOne(description)" );
|
||||||
|
Assert.assertTrue( EntityGraphs.areEqual( a, b ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDifferentComplexGraphsEqual() {
|
||||||
|
EntityGraph<GraphParsingTestEntity> a = parseGraph( "map.key(name, description), name, linkToOne(description), description" );
|
||||||
|
EntityGraph<GraphParsingTestEntity> b = parseGraph( "description, map.value(description, name), name, linkToOne(description)" );
|
||||||
|
Assert.assertFalse( EntityGraphs.areEqual( a, b ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testNullsEqual() {
|
||||||
|
Assert.assertTrue( EntityGraphs.areEqual( (EntityGraph<GraphParsingTestEntity>) null, (EntityGraph<GraphParsingTestEntity>) null ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testNullAndNonNullEqual() {
|
||||||
|
EntityGraph<GraphParsingTestEntity> graph = parseGraph( "name " );
|
||||||
|
Assert.assertFalse( EntityGraphs.areEqual( graph, (EntityGraph<GraphParsingTestEntity>) null ) );
|
||||||
|
Assert.assertFalse( EntityGraphs.areEqual( (EntityGraph<GraphParsingTestEntity>) null, graph ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testBasicMerge() {
|
||||||
|
EntityGraph<GraphParsingTestEntity> g1 = parseGraph( "name" );
|
||||||
|
EntityGraph<GraphParsingTestEntity> g2 = parseGraph( "description" );
|
||||||
|
EntityGraph<GraphParsingTestEntity> expected = parseGraph( "name, description " );
|
||||||
|
checkMerge( expected, g1, g2 );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testLinkMerge() {
|
||||||
|
EntityGraph<GraphParsingTestEntity> g1 = parseGraph( "linkToOne(name)" );
|
||||||
|
EntityGraph<GraphParsingTestEntity> g2 = parseGraph( "linkToOne(description)" );
|
||||||
|
EntityGraph<GraphParsingTestEntity> expected = parseGraph( "linkToOne(name, description) " );
|
||||||
|
checkMerge( expected, g1, g2 );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMapKeyMerge() {
|
||||||
|
EntityGraph<GraphParsingTestEntity> g1 = parseGraph( "map.key(name)" );
|
||||||
|
EntityGraph<GraphParsingTestEntity> g2 = parseGraph( "map.key(description)" );
|
||||||
|
EntityGraph<GraphParsingTestEntity> expected = parseGraph( "map.key(name, description) " );
|
||||||
|
checkMerge( expected, g1, g2 );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMapValueMerge() {
|
||||||
|
EntityGraph<GraphParsingTestEntity> g1 = parseGraph( "map.value(name)" );
|
||||||
|
EntityGraph<GraphParsingTestEntity> g2 = parseGraph( "map.value(description)" );
|
||||||
|
EntityGraph<GraphParsingTestEntity> expected = parseGraph( "map.value(name, description) " );
|
||||||
|
checkMerge( expected, g1, g2 );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestForIssue( jiraKey = "HHH-14264" )
|
||||||
|
public void testRootGraphAppliesToChildEntityClass() {
|
||||||
|
RootGraphImplementor<GraphParsingTestEntity> rootGraphImplementor = parseGraph( GraphParsingTestEntity.class, "name, description" );
|
||||||
|
Assert.assertTrue( rootGraphImplementor.appliesTo( GraphParsingTestSubentity.class ) );
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,81 @@
|
|||||||
|
package org.hibernate.graph;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import javax.persistence.Basic;
|
||||||
|
import javax.persistence.CascadeType;
|
||||||
|
import javax.persistence.ElementCollection;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.FetchType;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.ManyToOne;
|
||||||
|
import javax.persistence.OneToMany;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
public class GraphParsingTestEntity {
|
||||||
|
|
||||||
|
private String id;
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
private GraphParsingTestEntity linkToOne;
|
||||||
|
private GraphParsingTestEntity linkToOneLazy;
|
||||||
|
|
||||||
|
private Map<GraphParsingTestEntity, GraphParsingTestEntity> map;
|
||||||
|
|
||||||
|
@Id
|
||||||
|
public String getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(String id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Basic
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ManyToOne( fetch = FetchType.EAGER )
|
||||||
|
public GraphParsingTestEntity getLinkToOne() {
|
||||||
|
return linkToOne;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLinkToOne(GraphParsingTestEntity linkToOne) {
|
||||||
|
this.linkToOne = linkToOne;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ManyToOne( fetch = FetchType.LAZY )
|
||||||
|
public GraphParsingTestEntity getLinkToOneLazy() {
|
||||||
|
return linkToOneLazy;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLinkToOneLazy(GraphParsingTestEntity linkToOneLazy) {
|
||||||
|
this.linkToOneLazy = linkToOneLazy;
|
||||||
|
}
|
||||||
|
|
||||||
|
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
|
||||||
|
@ElementCollection(targetClass = GraphParsingTestEntity.class)
|
||||||
|
public Map<GraphParsingTestEntity, GraphParsingTestEntity> getMap() {
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMap(Map<GraphParsingTestEntity, GraphParsingTestEntity> map) {
|
||||||
|
this.map = map;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Basic
|
||||||
|
public String getDescription() {
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDescription(String description) {
|
||||||
|
this.description = description;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,20 @@
|
|||||||
|
package org.hibernate.graph;
|
||||||
|
|
||||||
|
import javax.persistence.Basic;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
public class GraphParsingTestSubentity extends GraphParsingTestEntity {
|
||||||
|
|
||||||
|
private String sub;
|
||||||
|
|
||||||
|
@Basic
|
||||||
|
public String getSub() {
|
||||||
|
return sub;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSub(String sub) {
|
||||||
|
this.sub = sub;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,73 @@
|
|||||||
|
/*
|
||||||
|
* 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.test.foreignkeys.disabled;
|
||||||
|
|
||||||
|
import static org.hamcrest.core.Is.is;
|
||||||
|
import static org.junit.Assert.assertThat;
|
||||||
|
|
||||||
|
import java.util.stream.StreamSupport;
|
||||||
|
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.JoinColumn;
|
||||||
|
import javax.persistence.ManyToOne;
|
||||||
|
|
||||||
|
import org.hibernate.boot.Metadata;
|
||||||
|
import org.hibernate.boot.MetadataSources;
|
||||||
|
import org.hibernate.boot.registry.StandardServiceRegistry;
|
||||||
|
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
|
||||||
|
import org.hibernate.cfg.Environment;
|
||||||
|
import org.hibernate.mapping.Table;
|
||||||
|
import org.hibernate.testing.TestForIssue;
|
||||||
|
import org.hibernate.testing.junit4.BaseUnitTestCase;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Yanming Zhou
|
||||||
|
*/
|
||||||
|
public class DefaultConstraintModeTest extends BaseUnitTestCase {
|
||||||
|
|
||||||
|
private static final String TABLE_NAME = "TestEntity";
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestForIssue(jiraKey = "HHH-14253")
|
||||||
|
public void testForeignKeyShouldNotBeCreated() {
|
||||||
|
testForeignKeyCreation(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestForIssue(jiraKey = "HHH-14253")
|
||||||
|
public void testForeignKeyShouldBeCreated() {
|
||||||
|
testForeignKeyCreation(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void testForeignKeyCreation(boolean created) {
|
||||||
|
StandardServiceRegistry ssr = new StandardServiceRegistryBuilder()
|
||||||
|
.applySetting(Environment.HBM2DDL_DEFAULT_CONSTRAINT_MODE, created ? "CONSTRAINT" : "NO_CONSTRAINT").build();
|
||||||
|
Metadata metadata = new MetadataSources(ssr).addAnnotatedClass(TestEntity.class).buildMetadata();
|
||||||
|
assertThat(findTable(metadata, TABLE_NAME).getForeignKeys().isEmpty(), is(!created));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Table findTable(Metadata metadata, String tableName) {
|
||||||
|
return StreamSupport.stream(metadata.getDatabase().getNamespaces().spliterator(), false)
|
||||||
|
.flatMap(namespace -> namespace.getTables().stream()).filter(t -> t.getName().equals(tableName))
|
||||||
|
.findFirst().orElse(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@javax.persistence.Table(name = TABLE_NAME)
|
||||||
|
public static class TestEntity {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@ManyToOne
|
||||||
|
@JoinColumn
|
||||||
|
private TestEntity mate;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,75 @@
|
|||||||
|
package org.hibernate.test.inheritance;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Map;
|
||||||
|
import javax.persistence.Column;
|
||||||
|
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 javax.persistence.UniqueConstraint;
|
||||||
|
|
||||||
|
import org.hibernate.cfg.AvailableSettings;
|
||||||
|
|
||||||
|
import org.hibernate.testing.TestForIssue;
|
||||||
|
import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Vlad Paln
|
||||||
|
* @author Nathan Xu
|
||||||
|
*/
|
||||||
|
@TestForIssue( jiraKey = "HHH-14234" )
|
||||||
|
public class DenormalizedTablePhysicalIncludedTableConstraintTest extends BaseNonConfigCoreFunctionalTestCase {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void addSettings(Map settings) {
|
||||||
|
settings.put( AvailableSettings.HBM2DDL_HALT_ON_ERROR, Boolean.TRUE.toString() );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Class<?>[] getAnnotatedClasses() {
|
||||||
|
return new Class<?>[] {
|
||||||
|
SuperClass.class,
|
||||||
|
SubClass.class
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUniqueConstraintFromSupTableNotAppliedToSubTable() {
|
||||||
|
// Unique constraint should be unique in db
|
||||||
|
// Without fixing, exception will be thrown when unique constraint in 'SUPTABLE' is applied to 'SUBTABLE' as well
|
||||||
|
// Both table names are uppercase to accommodate HANA dialect (see https://stackoverflow.com/questions/29974507/sap-hana-invalid-table-name)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Entity(name = "SuperClass")
|
||||||
|
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
|
||||||
|
@Table( name = "SUPTABLE",
|
||||||
|
uniqueConstraints = {
|
||||||
|
@UniqueConstraint( name = "UK",
|
||||||
|
columnNames = {"colOne", "colTwo"})
|
||||||
|
}
|
||||||
|
)
|
||||||
|
static class SuperClass implements Serializable {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@GeneratedValue
|
||||||
|
Long id;
|
||||||
|
|
||||||
|
@Column(name = "colOne")
|
||||||
|
Long colOne;
|
||||||
|
|
||||||
|
@Column(name = "colTwo")
|
||||||
|
Long colTwo;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Entity(name = "SubClass")
|
||||||
|
@Table( name = "SUBTABLE" )
|
||||||
|
static class SubClass extends SuperClass {
|
||||||
|
|
||||||
|
@Column(name = "colThree")
|
||||||
|
Long colThree;
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user