Search in sources :

Example 1 with IdClass

use of jakarta.persistence.IdClass in project hibernate-orm by hibernate.

the class JPAXMLOverriddenAnnotationReader method getIdClass.

private IdClass getIdClass(ManagedType root, XMLContext.Default defaults) {
    JaxbIdClass element = root instanceof EntityOrMappedSuperclass ? ((EntityOrMappedSuperclass) root).getIdClass() : null;
    if (element != null) {
        String className = element.getClazz();
        if (className != null) {
            AnnotationDescriptor ad = new AnnotationDescriptor(IdClass.class);
            Class<?> clazz;
            try {
                clazz = classLoaderAccess.classForName(XMLContext.buildSafeClassName(className, defaults));
            } catch (ClassLoadingException e) {
                throw new AnnotationException("Unable to find id-class: " + className, e);
            }
            ad.setValue("value", clazz);
            return AnnotationFactory.create(ad);
        } else {
            throw new AnnotationException("id-class without class. " + SCHEMA_VALIDATION);
        }
    } else if (defaults.canUseJavaAnnotations()) {
        return getPhysicalAnnotation(IdClass.class);
    } else {
        return null;
    }
}
Also used : AnnotationDescriptor(org.hibernate.annotations.common.annotationfactory.AnnotationDescriptor) IdClass(jakarta.persistence.IdClass) JaxbIdClass(org.hibernate.boot.jaxb.mapping.spi.JaxbIdClass) ClassLoadingException(org.hibernate.boot.registry.classloading.spi.ClassLoadingException) JaxbIdClass(org.hibernate.boot.jaxb.mapping.spi.JaxbIdClass) EntityOrMappedSuperclass(org.hibernate.boot.jaxb.mapping.spi.EntityOrMappedSuperclass) AnnotationException(org.hibernate.AnnotationException)

Example 2 with IdClass

use of jakarta.persistence.IdClass in project hibernate-orm by hibernate.

the class AnnotationBinder method isIdClassPkOfTheAssociatedEntity.

private static boolean isIdClassPkOfTheAssociatedEntity(InheritanceState.ElementsToProcess elementsToProcess, XClass compositeClass, PropertyData inferredData, PropertyData baseInferredData, AccessType propertyAccessor, Map<XClass, InheritanceState> inheritanceStatePerClass, MetadataBuildingContext context) {
    if (elementsToProcess.getIdPropertyCount() == 1) {
        final PropertyData idPropertyOnBaseClass = getUniqueIdPropertyFromBaseClass(inferredData, baseInferredData, propertyAccessor, context);
        final InheritanceState state = inheritanceStatePerClass.get(idPropertyOnBaseClass.getClassOrElement());
        if (state == null) {
            // while it is likely a user error, let's consider it is something that might happen
            return false;
        }
        final XClass associatedClassWithIdClass = state.getClassWithIdClass(true);
        if (associatedClassWithIdClass == null) {
            // Let's not do this thorough checking but do some extra validation
            return hasToOneAnnotation(idPropertyOnBaseClass.getProperty());
        } else {
            IdClass idClass = associatedClassWithIdClass.getAnnotation(IdClass.class);
            // noinspection unchecked
            return context.getBootstrapContext().getReflectionManager().toXClass(idClass.value()).equals(compositeClass);
        }
    } else {
        return false;
    }
}
Also used : InheritanceState.getSuperclassInheritanceState(org.hibernate.cfg.InheritanceState.getSuperclassInheritanceState) IdClass(jakarta.persistence.IdClass) XClass(org.hibernate.annotations.common.reflection.XClass)

Example 3 with IdClass

use of jakarta.persistence.IdClass 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
    XClass classWithIdClass = inheritanceState.getClassWithIdClass(false);
    if (classWithIdClass != null) {
        IdClass idClass = classWithIdClass.getAnnotation(IdClass.class);
        // noinspection unchecked
        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 Hibernate's internal way)
        final boolean isFakeIdClass = isIdClassPkOfTheAssociatedEntity(elementsToProcess, compositeClass, inferredData, baseInferredData, propertyAccessor, inheritanceStatePerClass, context);
        if (isFakeIdClass) {
            return false;
        }
        boolean ignoreIdAnnotations = entityBinder.isIgnoreIdAnnotations();
        entityBinder.setIgnoreIdAnnotations(true);
        propertyHolder.setInIdClass(true);
        bindIdClass(inferredData, baseInferredData, propertyHolder, propertyAccessor, entityBinder, context, inheritanceStatePerClass);
        propertyHolder.setInIdClass(null);
        Component mapper = fillComponent(propertyHolder, new PropertyPreloadedData(propertyAccessor, PropertyPath.IDENTIFIER_MAPPER_PROPERTY, compositeClass), baseInferredData, propertyAccessor, false, entityBinder, true, true, false, null, null, 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 = 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);
        for (Property prop : mapper.getProperties()) {
            idPropertiesIfIdClass.add(prop.getName());
        }
        return true;
    } else {
        return false;
    }
}
Also used : IdClass(jakarta.persistence.IdClass) Component(org.hibernate.mapping.Component) XClass(org.hibernate.annotations.common.reflection.XClass) Property(org.hibernate.mapping.Property) XProperty(org.hibernate.annotations.common.reflection.XProperty)

Aggregations

IdClass (jakarta.persistence.IdClass)3 XClass (org.hibernate.annotations.common.reflection.XClass)2 AnnotationException (org.hibernate.AnnotationException)1 AnnotationDescriptor (org.hibernate.annotations.common.annotationfactory.AnnotationDescriptor)1 XProperty (org.hibernate.annotations.common.reflection.XProperty)1 EntityOrMappedSuperclass (org.hibernate.boot.jaxb.mapping.spi.EntityOrMappedSuperclass)1 JaxbIdClass (org.hibernate.boot.jaxb.mapping.spi.JaxbIdClass)1 ClassLoadingException (org.hibernate.boot.registry.classloading.spi.ClassLoadingException)1 InheritanceState.getSuperclassInheritanceState (org.hibernate.cfg.InheritanceState.getSuperclassInheritanceState)1 Component (org.hibernate.mapping.Component)1 Property (org.hibernate.mapping.Property)1