use of org.hibernate.mapping.PersistentClass in project hibernate-orm by hibernate.
the class InFlightMetadataCollectorImpl method processExportableProducers.
private void processExportableProducers() {
// for now we only handle id generators as ExportableProducers
final Dialect dialect = getDatabase().getJdbcEnvironment().getDialect();
final String defaultCatalog = extractName(getDatabase().getDefaultNamespace().getName().getCatalog(), dialect);
final String defaultSchema = extractName(getDatabase().getDefaultNamespace().getName().getSchema(), dialect);
for (PersistentClass entityBinding : entityBindingMap.values()) {
if (entityBinding.isInherited()) {
continue;
}
handleIdentifierValueBinding(entityBinding.getIdentifier(), dialect, defaultCatalog, defaultSchema, (RootClass) entityBinding);
}
for (Collection collection : collectionBindingMap.values()) {
if (!IdentifierCollection.class.isInstance(collection)) {
continue;
}
handleIdentifierValueBinding(((IdentifierCollection) collection).getIdentifier(), dialect, defaultCatalog, defaultSchema, null);
}
}
use of org.hibernate.mapping.PersistentClass in project hibernate-orm by hibernate.
the class AnnotationBinder method bindIdClass.
private static void bindIdClass(String generatorType, String generatorName, PropertyData inferredData, PropertyData baseInferredData, Ejb3Column[] columns, PropertyHolder propertyHolder, boolean isComposite, AccessType propertyAccessor, EntityBinder entityBinder, boolean isEmbedded, boolean isIdentifierMapper, MetadataBuildingContext buildingContext, Map<XClass, InheritanceState> inheritanceStatePerClass) {
/*
* Fill simple value and property since and Id is a property
*/
PersistentClass persistentClass = propertyHolder.getPersistentClass();
if (!(persistentClass instanceof RootClass)) {
throw new AnnotationException("Unable to define/override @Id(s) on a subclass: " + propertyHolder.getEntityName());
}
RootClass rootClass = (RootClass) persistentClass;
String persistentClassName = rootClass.getClassName();
SimpleValue id;
final String propertyName = inferredData.getPropertyName();
if (isComposite) {
id = fillComponent(propertyHolder, inferredData, baseInferredData, propertyAccessor, false, entityBinder, isEmbedded, isIdentifierMapper, false, buildingContext, inheritanceStatePerClass);
Component componentId = (Component) id;
componentId.setKey(true);
if (rootClass.getIdentifier() != null) {
throw new AnnotationException(componentId.getComponentClassName() + " must not have @Id properties when used as an @EmbeddedId");
}
if (componentId.getPropertySpan() == 0) {
throw new AnnotationException(componentId.getComponentClassName() + " has no persistent id property");
}
// tuplizers
XProperty property = inferredData.getProperty();
setupComponentTuplizer(property, componentId);
} else {
for (Ejb3Column column : columns) {
// this is an id
column.forceNotNull();
}
SimpleValueBinder value = new SimpleValueBinder();
value.setPropertyName(propertyName);
value.setReturnedClassName(inferredData.getTypeName());
value.setColumns(columns);
value.setPersistentClassName(persistentClassName);
value.setBuildingContext(buildingContext);
value.setType(inferredData.getProperty(), inferredData.getClassOrElement(), persistentClassName, null);
value.setAccessType(propertyAccessor);
id = value.make();
}
rootClass.setIdentifier(id);
SecondPass secondPass = new IdGeneratorResolverSecondPass(id, inferredData.getProperty(), generatorType, generatorName, buildingContext);
buildingContext.getMetadataCollector().addSecondPass(secondPass);
if (isEmbedded) {
rootClass.setEmbeddedIdentifier(inferredData.getPropertyClass() == null);
} else {
PropertyBinder binder = new PropertyBinder();
binder.setName(propertyName);
binder.setValue(id);
binder.setAccessType(inferredData.getDefaultAccess());
binder.setProperty(inferredData.getProperty());
Property prop = binder.makeProperty();
rootClass.setIdentifierProperty(prop);
// if the id property is on a superclass, update the metamodel
final org.hibernate.mapping.MappedSuperclass superclass = BinderHelper.getMappedSuperclassOrNull(inferredData.getDeclaringClass(), inheritanceStatePerClass, buildingContext);
if (superclass != null) {
superclass.setDeclaredIdentifierProperty(prop);
} else {
// we know the property is on the actual entity
rootClass.setDeclaredIdentifierProperty(prop);
}
}
}
use of org.hibernate.mapping.PersistentClass in project hibernate-orm by hibernate.
the class AnnotationBinder method bindClass.
/**
* Bind a class having JSR175 annotations. Subclasses <b>have to</b> be bound after its parent class.
*
* @param clazzToProcess entity to bind as {@code XClass} instance
* @param inheritanceStatePerClass Meta data about the inheritance relationships for all mapped classes
*
* @throws MappingException in case there is a configuration error
*/
public static void bindClass(XClass clazzToProcess, Map<XClass, InheritanceState> inheritanceStatePerClass, MetadataBuildingContext context) throws MappingException {
// @Entity and @MappedSuperclass on the same class leads to a NPE down the road
if (clazzToProcess.isAnnotationPresent(Entity.class) && clazzToProcess.isAnnotationPresent(MappedSuperclass.class)) {
throw new AnnotationException("An entity cannot be annotated with both @Entity and @MappedSuperclass: " + clazzToProcess.getName());
}
// TODO: be more strict with secondarytable allowance (not for ids, not for secondary table join columns etc)
InheritanceState inheritanceState = inheritanceStatePerClass.get(clazzToProcess);
AnnotatedClassType classType = context.getMetadataCollector().getClassType(clazzToProcess);
// Queries declared in MappedSuperclass should be usable in Subclasses
if (AnnotatedClassType.EMBEDDABLE_SUPERCLASS.equals(classType)) {
bindQueries(clazzToProcess, context);
bindTypeDefs(clazzToProcess, context);
bindFilterDefs(clazzToProcess, context);
}
if (!isEntityClassType(clazzToProcess, classType)) {
return;
}
if (LOG.isDebugEnabled()) {
LOG.debugf("Binding entity from annotated class: %s", clazzToProcess.getName());
}
PersistentClass superEntity = getSuperEntity(clazzToProcess, inheritanceStatePerClass, context, inheritanceState);
PersistentClass persistentClass = makePersistentClass(inheritanceState, superEntity, context);
Entity entityAnn = clazzToProcess.getAnnotation(Entity.class);
org.hibernate.annotations.Entity hibEntityAnn = clazzToProcess.getAnnotation(org.hibernate.annotations.Entity.class);
EntityBinder entityBinder = new EntityBinder(entityAnn, hibEntityAnn, clazzToProcess, persistentClass, context);
entityBinder.setInheritanceState(inheritanceState);
bindQueries(clazzToProcess, context);
bindFilterDefs(clazzToProcess, context);
bindTypeDefs(clazzToProcess, context);
bindFetchProfiles(clazzToProcess, context);
BinderHelper.bindAnyMetaDefs(clazzToProcess, context);
String schema = "";
// might be no @Table annotation on the annotated class
String table = "";
String catalog = "";
List<UniqueConstraintHolder> uniqueConstraints = new ArrayList<>();
javax.persistence.Table tabAnn = null;
if (clazzToProcess.isAnnotationPresent(javax.persistence.Table.class)) {
tabAnn = clazzToProcess.getAnnotation(javax.persistence.Table.class);
table = tabAnn.name();
schema = tabAnn.schema();
catalog = tabAnn.catalog();
uniqueConstraints = TableBinder.buildUniqueConstraintHolders(tabAnn.uniqueConstraints());
}
Ejb3JoinColumn[] inheritanceJoinedColumns = makeInheritanceJoinColumns(clazzToProcess, context, inheritanceState, superEntity);
final Ejb3DiscriminatorColumn discriminatorColumn;
if (InheritanceType.SINGLE_TABLE.equals(inheritanceState.getType())) {
discriminatorColumn = processSingleTableDiscriminatorProperties(clazzToProcess, context, inheritanceState, entityBinder);
} else if (InheritanceType.JOINED.equals(inheritanceState.getType())) {
discriminatorColumn = processJoinedDiscriminatorProperties(clazzToProcess, context, inheritanceState, entityBinder);
} else {
discriminatorColumn = null;
}
entityBinder.setProxy(clazzToProcess.getAnnotation(Proxy.class));
entityBinder.setBatchSize(clazzToProcess.getAnnotation(BatchSize.class));
entityBinder.setWhere(clazzToProcess.getAnnotation(Where.class));
applyCacheSettings(entityBinder, clazzToProcess, context);
bindFilters(clazzToProcess, entityBinder, context);
entityBinder.bindEntity();
if (inheritanceState.hasTable()) {
Check checkAnn = clazzToProcess.getAnnotation(Check.class);
String constraints = checkAnn == null ? null : checkAnn.constraints();
EntityTableXref denormalizedTableXref = inheritanceState.hasDenormalizedTable() ? context.getMetadataCollector().getEntityTableXref(superEntity.getEntityName()) : null;
entityBinder.bindTable(schema, catalog, table, uniqueConstraints, constraints, denormalizedTableXref);
} else {
if (clazzToProcess.isAnnotationPresent(Table.class)) {
LOG.invalidTableAnnotation(clazzToProcess.getName());
}
if (inheritanceState.getType() == InheritanceType.SINGLE_TABLE) {
// we at least need to properly set up the EntityTableXref
entityBinder.bindTableForDiscriminatedSubclass(context.getMetadataCollector().getEntityTableXref(superEntity.getEntityName()));
}
}
PropertyHolder propertyHolder = PropertyHolderBuilder.buildPropertyHolder(clazzToProcess, persistentClass, entityBinder, context, inheritanceStatePerClass);
javax.persistence.SecondaryTable secTabAnn = clazzToProcess.getAnnotation(javax.persistence.SecondaryTable.class);
javax.persistence.SecondaryTables secTabsAnn = clazzToProcess.getAnnotation(javax.persistence.SecondaryTables.class);
entityBinder.firstLevelSecondaryTablesBinding(secTabAnn, secTabsAnn);
OnDelete onDeleteAnn = clazzToProcess.getAnnotation(OnDelete.class);
boolean onDeleteAppropriate = false;
// todo : sucks that this is separate from RootClass distinction
final boolean isInheritanceRoot = !inheritanceState.hasParents();
final boolean hasSubclasses = inheritanceState.hasSiblings();
if (InheritanceType.JOINED.equals(inheritanceState.getType())) {
if (inheritanceState.hasParents()) {
onDeleteAppropriate = true;
final JoinedSubclass jsc = (JoinedSubclass) persistentClass;
SimpleValue key = new DependantValue(context, jsc.getTable(), jsc.getIdentifier());
jsc.setKey(key);
ForeignKey fk = clazzToProcess.getAnnotation(ForeignKey.class);
if (fk != null && !BinderHelper.isEmptyAnnotationValue(fk.name())) {
key.setForeignKeyName(fk.name());
} else {
final PrimaryKeyJoinColumn pkJoinColumn = clazzToProcess.getAnnotation(PrimaryKeyJoinColumn.class);
final PrimaryKeyJoinColumns pkJoinColumns = clazzToProcess.getAnnotation(PrimaryKeyJoinColumns.class);
if (pkJoinColumns != null && pkJoinColumns.foreignKey().value() == ConstraintMode.NO_CONSTRAINT) {
// don't apply a constraint based on ConstraintMode
key.setForeignKeyName("none");
} else if (pkJoinColumns != null && !StringHelper.isEmpty(pkJoinColumns.foreignKey().name())) {
key.setForeignKeyName(pkJoinColumns.foreignKey().name());
} else if (pkJoinColumn != null && pkJoinColumn.foreignKey().value() == ConstraintMode.NO_CONSTRAINT) {
// don't apply a constraint based on ConstraintMode
key.setForeignKeyName("none");
} else if (pkJoinColumn != null && !StringHelper.isEmpty(pkJoinColumn.foreignKey().name())) {
key.setForeignKeyName(pkJoinColumn.foreignKey().name());
}
}
if (onDeleteAnn != null) {
key.setCascadeDeleteEnabled(OnDeleteAction.CASCADE.equals(onDeleteAnn.action()));
} else {
key.setCascadeDeleteEnabled(false);
}
// we are never in a second pass at that stage, so queue it
context.getMetadataCollector().addSecondPass(new JoinedSubclassFkSecondPass(jsc, inheritanceJoinedColumns, key, context));
context.getMetadataCollector().addSecondPass(new CreateKeySecondPass(jsc));
}
if (isInheritanceRoot) {
// (it is perfectly valid for joined subclasses to not have discriminators).
if (discriminatorColumn != null) {
// we have a discriminator column
if (hasSubclasses || !discriminatorColumn.isImplicit()) {
bindDiscriminatorColumnToRootPersistentClass((RootClass) persistentClass, discriminatorColumn, entityBinder.getSecondaryTables(), propertyHolder, context);
// bind it again since the type might have changed
entityBinder.bindDiscriminatorValue();
}
}
}
} else if (InheritanceType.SINGLE_TABLE.equals(inheritanceState.getType())) {
if (isInheritanceRoot) {
if (hasSubclasses || !discriminatorColumn.isImplicit()) {
bindDiscriminatorColumnToRootPersistentClass((RootClass) persistentClass, discriminatorColumn, entityBinder.getSecondaryTables(), propertyHolder, context);
// bind it again since the type might have changed
entityBinder.bindDiscriminatorValue();
}
}
}
if (onDeleteAnn != null && !onDeleteAppropriate) {
LOG.invalidOnDeleteAnnotation(propertyHolder.getEntityName());
}
// try to find class level generators
HashMap<String, IdentifierGeneratorDefinition> classGenerators = buildGenerators(clazzToProcess, context);
// check properties
final InheritanceState.ElementsToProcess elementsToProcess = inheritanceState.getElementsToProcess();
inheritanceState.postProcess(persistentClass, entityBinder);
final boolean subclassAndSingleTableStrategy = inheritanceState.getType() == InheritanceType.SINGLE_TABLE && inheritanceState.hasParents();
Set<String> idPropertiesIfIdClass = new HashSet<>();
boolean isIdClass = mapAsIdClass(inheritanceStatePerClass, inheritanceState, persistentClass, entityBinder, propertyHolder, elementsToProcess, idPropertiesIfIdClass, context);
if (!isIdClass) {
entityBinder.setWrapIdsInEmbeddedComponents(elementsToProcess.getIdPropertyCount() > 1);
}
processIdPropertiesIfNotAlready(inheritanceStatePerClass, context, persistentClass, entityBinder, propertyHolder, classGenerators, elementsToProcess, subclassAndSingleTableStrategy, idPropertiesIfIdClass);
if (!inheritanceState.hasParents()) {
final RootClass rootClass = (RootClass) persistentClass;
context.getMetadataCollector().addSecondPass(new CreateKeySecondPass(rootClass));
} else {
superEntity.addSubclass((Subclass) persistentClass);
}
context.getMetadataCollector().addEntityBinding(persistentClass);
// Process secondary tables and complementary definitions (ie o.h.a.Table)
context.getMetadataCollector().addSecondPass(new SecondaryTableSecondPass(entityBinder, propertyHolder, clazzToProcess));
// add process complementary Table definition (index & all)
entityBinder.processComplementaryTableDefinitions(clazzToProcess.getAnnotation(org.hibernate.annotations.Table.class));
entityBinder.processComplementaryTableDefinitions(clazzToProcess.getAnnotation(org.hibernate.annotations.Tables.class));
entityBinder.processComplementaryTableDefinitions(tabAnn);
}
use of org.hibernate.mapping.PersistentClass in project hibernate-orm by hibernate.
the class UnionSubclassEntityPersister method generateSubquery.
protected String generateSubquery(PersistentClass model, Mapping mapping) {
Dialect dialect = getFactory().getDialect();
Settings settings = getFactory().getSettings();
if (!model.hasSubclasses()) {
return model.getTable().getQualifiedName(dialect, settings.getDefaultCatalogName(), settings.getDefaultSchemaName());
}
HashSet columns = new LinkedHashSet();
Iterator titer = model.getSubclassTableClosureIterator();
while (titer.hasNext()) {
Table table = (Table) titer.next();
if (!table.isAbstractUnionTable()) {
Iterator citer = table.getColumnIterator();
while (citer.hasNext()) {
columns.add(citer.next());
}
}
}
StringBuilder buf = new StringBuilder().append("( ");
Iterator siter = new JoinedIterator(new SingletonIterator(model), model.getSubclassIterator());
while (siter.hasNext()) {
PersistentClass clazz = (PersistentClass) siter.next();
Table table = clazz.getTable();
if (!table.isAbstractUnionTable()) {
// TODO: move to .sql package!!
buf.append("select ");
Iterator citer = columns.iterator();
while (citer.hasNext()) {
Column col = (Column) citer.next();
if (!table.containsColumn(col)) {
int sqlType = col.getSqlTypeCode(mapping);
buf.append(dialect.getSelectClauseNullString(sqlType)).append(" as ");
}
buf.append(col.getQuotedName(dialect));
buf.append(", ");
}
buf.append(clazz.getSubclassId()).append(" as clazz_");
buf.append(" from ").append(table.getQualifiedName(dialect, settings.getDefaultCatalogName(), settings.getDefaultSchemaName()));
buf.append(" union ");
if (dialect.supportsUnionAll()) {
buf.append("all ");
}
}
}
if (buf.length() > 2) {
// chop the last union (all)
buf.setLength(buf.length() - (dialect.supportsUnionAll() ? 11 : 7));
}
return buf.append(" )").toString();
}
use of org.hibernate.mapping.PersistentClass in project hibernate-orm by hibernate.
the class MetamodelImpl method buildMappedSuperclassType.
// TODO remove / reduce @SW scope
@SuppressWarnings("unchecked")
private static MappedSuperclassTypeImpl<?> buildMappedSuperclassType(MappedSuperclass mappedSuperclass, MetadataContext context) {
final MappedSuperclass superMappedSuperclass = mappedSuperclass.getSuperMappedSuperclass();
AbstractIdentifiableType<?> superType = superMappedSuperclass == null ? null : locateOrBuildMappedsuperclassType(superMappedSuperclass, context);
// no mappedSuperclass, check for a super entity
if (superType == null) {
final PersistentClass superPersistentClass = mappedSuperclass.getSuperPersistentClass();
superType = superPersistentClass == null ? null : locateOrBuildEntityType(superPersistentClass, context);
}
final Class javaType = mappedSuperclass.getMappedClass();
MappedSuperclassTypeImpl mappedSuperclassType = new MappedSuperclassTypeImpl(javaType, mappedSuperclass, superType);
context.registerMappedSuperclassType(mappedSuperclass, mappedSuperclassType);
return mappedSuperclassType;
}
Aggregations