use of org.hibernate.mapping.SortableValue in project hibernate-orm by hibernate.
the class MappingModelCreationHelper method getPropertyOrder.
private static int[] getPropertyOrder(Value bootValueMapping, MappingModelCreationProcess creationProcess) {
final ComponentType componentType;
final boolean sorted;
if (bootValueMapping instanceof Collection) {
final Collection collectionBootValueMapping = (Collection) bootValueMapping;
componentType = (ComponentType) collectionBootValueMapping.getKey().getType();
assert ((SortableValue) collectionBootValueMapping.getKey()).isSorted();
sorted = ((SortableValue) collectionBootValueMapping.getKey()).isSorted();
} else {
final EntityType entityType = (EntityType) bootValueMapping.getType();
final Type identifierOrUniqueKeyType = entityType.getIdentifierOrUniqueKeyType(creationProcess.getCreationContext().getSessionFactory());
if (identifierOrUniqueKeyType instanceof ComponentType) {
componentType = (ComponentType) identifierOrUniqueKeyType;
if (bootValueMapping instanceof ToOne) {
assert ((ToOne) bootValueMapping).isSorted();
sorted = ((ToOne) bootValueMapping).isSorted();
} else {
// Assume one-to-many is sorted, because it always uses the primary key value
sorted = true;
}
} else {
// This happens when we have a one-to-many with a mapped-by associations that has a basic FK
return new int[] { 0 };
}
}
// Consider the reordering if available
if (!sorted && componentType.getOriginalPropertyOrder() != null) {
return componentType.getOriginalPropertyOrder();
} else // A value that came from the annotation model is already sorted appropriately
// so we use an "identity mapping"
{
final int columnSpan = componentType.getColumnSpan(creationProcess.getCreationContext().getBootModel());
final int[] propertyReordering = new int[columnSpan];
for (int i = 0; i < columnSpan; i++) {
propertyReordering[i] = i;
}
return propertyReordering;
}
}
use of org.hibernate.mapping.SortableValue in project hibernate-orm by hibernate.
the class ModelBinder method bindRootEntity.
private void bindRootEntity(EntityHierarchySourceImpl hierarchySource, RootClass rootEntityDescriptor) {
final MappingDocument mappingDocument = hierarchySource.getRoot().sourceMappingDocument();
bindBasicEntityValues(mappingDocument, hierarchySource.getRoot(), rootEntityDescriptor);
final Table primaryTable = bindEntityTableSpecification(mappingDocument, hierarchySource.getRoot().getPrimaryTable(), null, hierarchySource.getRoot(), rootEntityDescriptor);
rootEntityDescriptor.setTable(primaryTable);
if (log.isDebugEnabled()) {
log.debugf("Mapping class: %s -> %s", rootEntityDescriptor.getEntityName(), primaryTable.getName());
}
rootEntityDescriptor.setOptimisticLockStyle(hierarchySource.getOptimisticLockStyle());
rootEntityDescriptor.setMutable(hierarchySource.isMutable());
rootEntityDescriptor.setWhere(hierarchySource.getWhere());
rootEntityDescriptor.setExplicitPolymorphism(hierarchySource.isExplicitPolymorphism());
bindEntityIdentifier(mappingDocument, hierarchySource, rootEntityDescriptor);
if (hierarchySource.getVersionAttributeSource() != null) {
bindEntityVersion(mappingDocument, hierarchySource, rootEntityDescriptor);
}
if (hierarchySource.getDiscriminatorSource() != null) {
bindEntityDiscriminator(mappingDocument, hierarchySource, rootEntityDescriptor);
}
applyCaching(mappingDocument, hierarchySource.getCaching(), rootEntityDescriptor);
if (rootEntityDescriptor.getIdentifier() instanceof SortableValue) {
((SortableValue) rootEntityDescriptor.getIdentifier()).sortProperties();
}
// Primary key constraint
rootEntityDescriptor.createPrimaryKey();
bindAllEntityAttributes(mappingDocument, hierarchySource.getRoot(), rootEntityDescriptor);
if (hierarchySource.getNaturalIdCaching() != null) {
if (hierarchySource.getNaturalIdCaching().getRequested() == TruthValue.TRUE) {
rootEntityDescriptor.setNaturalIdCacheRegionName(hierarchySource.getNaturalIdCaching().getRegion());
}
}
}
use of org.hibernate.mapping.SortableValue in project hibernate-orm by hibernate.
the class TableBinder method bindFk.
public static void bindFk(PersistentClass referencedEntity, PersistentClass destinationEntity, AnnotatedJoinColumn[] columns, SimpleValue value, boolean unique, MetadataBuildingContext buildingContext) {
PersistentClass associatedClass;
if (destinationEntity != null) {
// overridden destination
associatedClass = destinationEntity;
} else {
associatedClass = columns[0].getPropertyHolder() == null ? null : columns[0].getPropertyHolder().getPersistentClass();
}
final String mappedByProperty = columns[0].getMappedBy();
if (StringHelper.isNotEmpty(mappedByProperty)) {
/*
* Get the columns of the mapped-by property
* copy them and link the copy to the actual value
*/
LOG.debugf("Retrieving property %s.%s", associatedClass.getEntityName(), mappedByProperty);
final Property property = associatedClass.getRecursiveProperty(columns[0].getMappedBy());
List<Column> mappedByColumns;
if (property.getValue() instanceof Collection) {
Collection collection = ((Collection) property.getValue());
Value element = collection.getElement();
if (element == null) {
throw new AnnotationException("Illegal use of mappedBy on both sides of the relationship: " + associatedClass.getEntityName() + "." + mappedByProperty);
}
mappedByColumns = element.getColumns();
} else {
mappedByColumns = property.getValue().getColumns();
}
for (Column column : mappedByColumns) {
columns[0].overrideFromReferencedColumnIfNecessary(column);
columns[0].linkValueUsingAColumnCopy(column, value);
}
} else if (columns[0].isImplicit()) {
/*
* if columns are implicit, then create the columns based on the
* referenced entity id columns
*/
List<Column> idColumns = referencedEntity instanceof JoinedSubclass ? referencedEntity.getKey().getColumns() : referencedEntity.getIdentifier().getColumns();
for (Column column : idColumns) {
columns[0].linkValueUsingDefaultColumnNaming(column, referencedEntity, value);
columns[0].overrideFromReferencedColumnIfNecessary(column);
}
} else {
int fkEnum = AnnotatedJoinColumn.checkReferencedColumnsType(columns, referencedEntity, buildingContext);
if (AnnotatedJoinColumn.NON_PK_REFERENCE == fkEnum) {
String referencedPropertyName;
if (value instanceof ToOne) {
referencedPropertyName = ((ToOne) value).getReferencedPropertyName();
} else if (value instanceof DependantValue) {
String propertyName = columns[0].getPropertyName();
if (propertyName != null) {
Collection collection = (Collection) referencedEntity.getRecursiveProperty(propertyName).getValue();
referencedPropertyName = collection.getReferencedPropertyName();
} else {
throw new AnnotationException("SecondaryTable JoinColumn cannot reference a non primary key");
}
} else {
throw new AssertionFailure("Do a property ref on an unexpected Value type: " + value.getClass().getName());
}
if (referencedPropertyName == null) {
throw new AssertionFailure("No property ref found while expected");
}
Property synthProp = referencedEntity.getReferencedProperty(referencedPropertyName);
if (synthProp == null) {
throw new AssertionFailure("Cannot find synthProp: " + referencedEntity.getEntityName() + "." + referencedPropertyName);
}
linkJoinColumnWithValueOverridingNameIfImplicit(referencedEntity, synthProp.getValue(), columns, value);
if (value instanceof SortableValue) {
((SortableValue) value).sortProperties();
}
} else {
if (AnnotatedJoinColumn.NO_REFERENCE == fkEnum) {
// implicit case, we hope PK and FK columns are in the same order
if (columns.length != referencedEntity.getIdentifier().getColumnSpan()) {
throw new AnnotationException("A Foreign key referring " + referencedEntity.getEntityName() + " from " + associatedClass.getEntityName() + " has the wrong number of column. should be " + referencedEntity.getIdentifier().getColumnSpan());
}
linkJoinColumnWithValueOverridingNameIfImplicit(referencedEntity, referencedEntity.getIdentifier(), columns, value);
if (value instanceof SortableValue) {
((SortableValue) value).sortProperties();
}
} else {
// Ensure the component is sorted so that we can simply set sorted to true on the to-one
if (referencedEntity.getKey() instanceof Component) {
((Component) referencedEntity.getKey()).sortProperties();
}
// explicit referencedColumnName
List<Column> idColumns = referencedEntity.getKey().getColumns();
// works cause the pk has to be on the primary table
Table table = referencedEntity.getTable();
if (idColumns.isEmpty()) {
LOG.debug("No column in the identifier!");
}
for (Column col : idColumns) {
boolean match = false;
// for each PK column, find the associated FK column.
Dialect dialect = buildingContext.getMetadataCollector().getDatabase().getJdbcEnvironment().getDialect();
final String colName = col.getQuotedName(dialect);
for (AnnotatedJoinColumn joinCol : columns) {
String referencedColumn = joinCol.getReferencedColumn();
referencedColumn = buildingContext.getMetadataCollector().getPhysicalColumnName(table, referencedColumn);
// In JPA 2 referencedColumnName is case-insensitive
if (referencedColumn.equalsIgnoreCase(colName)) {
// proper join column
if (joinCol.isNameDeferred()) {
joinCol.linkValueUsingDefaultColumnNaming(col, referencedEntity, value);
} else {
joinCol.linkWithValue(value);
}
joinCol.overrideFromReferencedColumnIfNecessary(col);
match = true;
break;
}
}
if (!match) {
throw new AnnotationException("Column name " + col.getName() + " of " + referencedEntity.getEntityName() + " not found in JoinColumns.referencedColumnName");
}
}
if (value instanceof ToOne) {
((ToOne) value).setSorted(true);
}
}
}
}
value.createForeignKey();
if (unique) {
value.createUniqueKey();
}
}
use of org.hibernate.mapping.SortableValue in project hibernate-orm by hibernate.
the class OneToOneSecondPass method buildJoinFromMappedBySide.
/**
* Builds the <code>Join</code> instance for the mapped by side of a <i>OneToOne</i> association using
* a join table.
* <p>
* Note:<br/>
* <ul>
* <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</li>.
* </ul>
* </p>
*/
private Join buildJoinFromMappedBySide(PersistentClass persistentClass, Property otherSideProperty, Join originalJoin) {
Join join = new Join();
join.setPersistentClass(persistentClass);
// no check constraints available on joins
join.setTable(originalJoin.getTable());
join.setInverse(true);
DependantValue key = new DependantValue(buildingContext, join.getTable(), persistentClass.getIdentifier());
// TODO support @ForeignKey
join.setKey(key);
join.setSequentialSelect(false);
// TODO support for inverse and optional
// perhaps not quite per-spec, but a Good Thing anyway
join.setOptional(true);
key.setCascadeDeleteEnabled(false);
for (Column column : otherSideProperty.getValue().getColumns()) {
Column copy = new Column();
copy.setLength(column.getLength());
copy.setScale(column.getScale());
copy.setValue(key);
copy.setName(column.getQuotedName());
copy.setNullable(column.isNullable());
copy.setPrecision(column.getPrecision());
copy.setUnique(column.isUnique());
copy.setSqlType(column.getSqlType());
copy.setCheckConstraint(column.getCheckConstraint());
copy.setComment(column.getComment());
copy.setDefaultValue(column.getDefaultValue());
column.setGeneratedAs(column.getGeneratedAs());
key.addColumn(copy);
}
if (otherSideProperty.getValue() instanceof SortableValue && !((SortableValue) otherSideProperty.getValue()).isSorted()) {
key.sortProperties();
}
persistentClass.addJoin(join);
return join;
}
Aggregations