use of org.hibernate.annotations.common.reflection.XClass in project hibernate-orm by hibernate.
the class AnnotationBinder method buildInheritanceStates.
/**
* For the mapped entities build some temporary data-structure containing information about the
* inheritance status of a class.
*
* @param orderedClasses Order list of all annotated entities and their mapped superclasses
*
* @return A map of {@code InheritanceState}s keyed against their {@code XClass}.
*/
public static Map<XClass, InheritanceState> buildInheritanceStates(List<XClass> orderedClasses, MetadataBuildingContext buildingContext) {
Map<XClass, InheritanceState> inheritanceStatePerClass = new HashMap<>(orderedClasses.size());
for (XClass clazz : orderedClasses) {
InheritanceState superclassState = InheritanceState.getSuperclassInheritanceState(clazz, inheritanceStatePerClass);
InheritanceState state = new InheritanceState(clazz, inheritanceStatePerClass, buildingContext);
if (superclassState != null) {
// the classes are ordered thus preventing an NPE
// FIXME if an entity has subclasses annotated @MappedSperclass wo sub @Entity this is wrong
superclassState.setHasSiblings(true);
InheritanceState superEntityState = InheritanceState.getInheritanceStateOfSuperEntity(clazz, inheritanceStatePerClass);
state.setHasParents(superEntityState != null);
final boolean nonDefault = state.getType() != null && !InheritanceType.SINGLE_TABLE.equals(state.getType());
if (superclassState.getType() != null) {
final boolean mixingStrategy = state.getType() != null && !state.getType().equals(superclassState.getType());
if (nonDefault && mixingStrategy) {
LOG.invalidSubStrategy(clazz.getName());
}
state.setType(superclassState.getType());
}
}
inheritanceStatePerClass.put(clazz, state);
}
return inheritanceStatePerClass;
}
use of org.hibernate.annotations.common.reflection.XClass in project hibernate-orm by hibernate.
the class AnnotationBinder method mapAsIdClass.
private static boolean mapAsIdClass(Map<XClass, InheritanceState> inheritanceStatePerClass, InheritanceState inheritanceState, PersistentClass persistentClass, EntityBinder entityBinder, PropertyHolder propertyHolder, InheritanceState.ElementsToProcess elementsToProcess, Set<String> idPropertiesIfIdClass, MetadataBuildingContext context) {
/*
* We are looking for @IdClass
* In general we map the id class as identifier using the mapping metadata of the main entity's properties
* and we create an identifier mapper containing the id properties of the main entity
*
* In JPA 2, there is a shortcut if the id class is the Pk of the associated class pointed to by the id
* it ought to be treated as an embedded and not a real IdClass (at least in the Hibernate's internal way
*/
XClass classWithIdClass = inheritanceState.getClassWithIdClass(false);
if (classWithIdClass != null) {
IdClass idClass = classWithIdClass.getAnnotation(IdClass.class);
XClass compositeClass = context.getBootstrapContext().getReflectionManager().toXClass(idClass.value());
PropertyData inferredData = new PropertyPreloadedData(entityBinder.getPropertyAccessType(), "id", compositeClass);
PropertyData baseInferredData = new PropertyPreloadedData(entityBinder.getPropertyAccessType(), "id", classWithIdClass);
AccessType propertyAccessor = entityBinder.getPropertyAccessor(compositeClass);
// In JPA 2, there is a shortcut if the IdClass is the Pk of the associated class pointed to by the id
// it ought to be treated as an embedded and not a real IdClass (at least in the Hibernate's internal way
final boolean isFakeIdClass = isIdClassPkOfTheAssociatedEntity(elementsToProcess, compositeClass, inferredData, baseInferredData, propertyAccessor, inheritanceStatePerClass, context);
if (isFakeIdClass) {
return false;
}
boolean isComponent = true;
String generatorType = "assigned";
String generator = BinderHelper.ANNOTATION_STRING_DEFAULT;
boolean ignoreIdAnnotations = entityBinder.isIgnoreIdAnnotations();
entityBinder.setIgnoreIdAnnotations(true);
propertyHolder.setInIdClass(true);
bindIdClass(generatorType, generator, inferredData, baseInferredData, null, propertyHolder, isComponent, propertyAccessor, entityBinder, true, false, context, inheritanceStatePerClass);
propertyHolder.setInIdClass(null);
inferredData = new PropertyPreloadedData(propertyAccessor, PropertyPath.IDENTIFIER_MAPPER_PROPERTY, compositeClass);
Component mapper = fillComponent(propertyHolder, inferredData, baseInferredData, propertyAccessor, false, entityBinder, true, true, false, context, inheritanceStatePerClass);
entityBinder.setIgnoreIdAnnotations(ignoreIdAnnotations);
persistentClass.setIdentifierMapper(mapper);
// If id definition is on a mapped superclass, update the mapping
final org.hibernate.mapping.MappedSuperclass superclass = BinderHelper.getMappedSuperclassOrNull(classWithIdClass, inheritanceStatePerClass, context);
if (superclass != null) {
superclass.setDeclaredIdentifierMapper(mapper);
} else {
// we are for sure on the entity
persistentClass.setDeclaredIdentifierMapper(mapper);
}
Property property = new Property();
property.setName(PropertyPath.IDENTIFIER_MAPPER_PROPERTY);
property.setUpdateable(false);
property.setInsertable(false);
property.setValue(mapper);
property.setPropertyAccessorName("embedded");
persistentClass.addProperty(property);
entityBinder.setIgnoreIdAnnotations(true);
Iterator properties = mapper.getPropertyIterator();
while (properties.hasNext()) {
idPropertiesIfIdClass.add(((Property) properties.next()).getName());
}
return true;
} else {
return false;
}
}
use of org.hibernate.annotations.common.reflection.XClass in project hibernate-orm by hibernate.
the class ClassPropertyHolder method addPropertyToMappedSuperclass.
private void addPropertyToMappedSuperclass(Property prop, XClass declaringClass) {
final Class type = getContext().getBootstrapContext().getReflectionManager().toClass(declaringClass);
MappedSuperclass superclass = getContext().getMetadataCollector().getMappedSuperclass(type);
superclass.addDeclaredProperty(prop);
}
use of org.hibernate.annotations.common.reflection.XClass in project hibernate-orm by hibernate.
the class CollectionBinder method bind.
public void bind() {
this.collection = createCollection(propertyHolder.getPersistentClass());
String role = StringHelper.qualify(propertyHolder.getPath(), propertyName);
LOG.debugf("Collection role: %s", role);
collection.setRole(role);
collection.setMappedByProperty(mappedBy);
if (property.isAnnotationPresent(MapKeyColumn.class) && mapKeyPropertyName != null) {
throw new AnnotationException("Cannot mix @javax.persistence.MapKey and @MapKeyColumn or @org.hibernate.annotations.MapKey " + "on the same collection: " + StringHelper.qualify(propertyHolder.getPath(), propertyName));
}
// set explicit type information
if (explicitType != null) {
final TypeDefinition typeDef = buildingContext.getMetadataCollector().getTypeDefinition(explicitType);
if (typeDef == null) {
collection.setTypeName(explicitType);
collection.setTypeParameters(explicitTypeParameters);
} else {
collection.setTypeName(typeDef.getTypeImplementorClass().getName());
collection.setTypeParameters(typeDef.getParameters());
}
}
// set laziness
defineFetchingStrategy();
collection.setBatchSize(batchSize);
collection.setMutable(!property.isAnnotationPresent(Immutable.class));
// work on association
boolean isMappedBy = !BinderHelper.isEmptyAnnotationValue(mappedBy);
final OptimisticLock lockAnn = property.getAnnotation(OptimisticLock.class);
final boolean includeInOptimisticLockChecks = (lockAnn != null) ? !lockAnn.excluded() : !isMappedBy;
collection.setOptimisticLocked(includeInOptimisticLockChecks);
Persister persisterAnn = property.getAnnotation(Persister.class);
if (persisterAnn != null) {
collection.setCollectionPersisterClass(persisterAnn.impl());
}
applySortingAndOrdering(collection);
// set cache
if (StringHelper.isNotEmpty(cacheConcurrencyStrategy)) {
collection.setCacheConcurrencyStrategy(cacheConcurrencyStrategy);
collection.setCacheRegionName(cacheRegionName);
}
// SQL overriding
SQLInsert sqlInsert = property.getAnnotation(SQLInsert.class);
SQLUpdate sqlUpdate = property.getAnnotation(SQLUpdate.class);
SQLDelete sqlDelete = property.getAnnotation(SQLDelete.class);
SQLDeleteAll sqlDeleteAll = property.getAnnotation(SQLDeleteAll.class);
Loader loader = property.getAnnotation(Loader.class);
if (sqlInsert != null) {
collection.setCustomSQLInsert(sqlInsert.sql().trim(), sqlInsert.callable(), ExecuteUpdateResultCheckStyle.fromExternalName(sqlInsert.check().toString().toLowerCase(Locale.ROOT)));
}
if (sqlUpdate != null) {
collection.setCustomSQLUpdate(sqlUpdate.sql(), sqlUpdate.callable(), ExecuteUpdateResultCheckStyle.fromExternalName(sqlUpdate.check().toString().toLowerCase(Locale.ROOT)));
}
if (sqlDelete != null) {
collection.setCustomSQLDelete(sqlDelete.sql(), sqlDelete.callable(), ExecuteUpdateResultCheckStyle.fromExternalName(sqlDelete.check().toString().toLowerCase(Locale.ROOT)));
}
if (sqlDeleteAll != null) {
collection.setCustomSQLDeleteAll(sqlDeleteAll.sql(), sqlDeleteAll.callable(), ExecuteUpdateResultCheckStyle.fromExternalName(sqlDeleteAll.check().toString().toLowerCase(Locale.ROOT)));
}
if (loader != null) {
collection.setLoaderName(loader.namedQuery());
}
if (isMappedBy && (property.isAnnotationPresent(JoinColumn.class) || property.isAnnotationPresent(JoinColumns.class) || propertyHolder.getJoinTable(property) != null)) {
String message = "Associations marked as mappedBy must not define database mappings like @JoinTable or @JoinColumn: ";
message += StringHelper.qualify(propertyHolder.getPath(), propertyName);
throw new AnnotationException(message);
}
if (!isMappedBy && oneToMany && property.isAnnotationPresent(OnDelete.class) && !property.isAnnotationPresent(JoinColumn.class)) {
String message = "Unidirectional one-to-many associations annotated with @OnDelete must define @JoinColumn: ";
message += StringHelper.qualify(propertyHolder.getPath(), propertyName);
throw new AnnotationException(message);
}
collection.setInverse(isMappedBy);
// many to many may need some second pass informations
if (!oneToMany && isMappedBy) {
buildingContext.getMetadataCollector().addMappedBy(getCollectionType().getName(), mappedBy, propertyName);
}
// TODO reducce tableBinder != null and oneToMany
XClass collectionType = getCollectionType();
if (inheritanceStatePerClass == null)
throw new AssertionFailure("inheritanceStatePerClass not set");
SecondPass sp = getSecondPass(fkJoinColumns, joinColumns, inverseJoinColumns, elementColumns, mapKeyColumns, mapKeyManyToManyColumns, isEmbedded, property, collectionType, ignoreNotFound, oneToMany, tableBinder, buildingContext);
if (collectionType.isAnnotationPresent(Embeddable.class) || // JPA 2
property.isAnnotationPresent(ElementCollection.class)) {
// do it right away, otherwise @ManyToOne on composite element call addSecondPass
// and raise a ConcurrentModificationException
// sp.doSecondPass( CollectionHelper.EMPTY_MAP );
buildingContext.getMetadataCollector().addSecondPass(sp, !isMappedBy);
} else {
buildingContext.getMetadataCollector().addSecondPass(sp, !isMappedBy);
}
buildingContext.getMetadataCollector().addCollectionBinding(collection);
// property building
PropertyBinder binder = new PropertyBinder();
binder.setName(propertyName);
binder.setValue(collection);
binder.setCascade(cascadeStrategy);
if (cascadeStrategy != null && cascadeStrategy.contains("delete-orphan")) {
collection.setOrphanDelete(true);
}
binder.setLazy(collection.isLazy());
final LazyGroup lazyGroupAnnotation = property.getAnnotation(LazyGroup.class);
if (lazyGroupAnnotation != null) {
binder.setLazyGroup(lazyGroupAnnotation.value());
}
binder.setAccessType(accessType);
binder.setProperty(property);
binder.setInsertable(insertable);
binder.setUpdatable(updatable);
Property prop = binder.makeProperty();
// we don't care about the join stuffs because the column is on the association table.
if (!declaringClassSet)
throw new AssertionFailure("DeclaringClass is not set in CollectionBinder while binding");
propertyHolder.addProperty(prop, declaringClass);
}
Aggregations