Search in sources :

Example 6 with JoinColumns

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

the class Ejb3XmlOneToManyTest method testMultipleJoinColumns.

@Test
public void testMultipleJoinColumns() throws Exception {
    reader = getReader(Entity2.class, "field1", "one-to-many.orm19.xml");
    assertAnnotationPresent(OneToMany.class);
    assertAnnotationNotPresent(JoinColumn.class);
    assertAnnotationPresent(JoinColumns.class);
    assertAnnotationNotPresent(JoinTable.class);
    JoinColumns joinColumnsAnno = reader.getAnnotation(JoinColumns.class);
    JoinColumn[] joinColumns = joinColumnsAnno.value();
    assertEquals(2, joinColumns.length);
    assertEquals("", joinColumns[0].name());
    assertEquals("", joinColumns[0].referencedColumnName());
    assertEquals("", joinColumns[0].table());
    assertEquals("", joinColumns[0].columnDefinition());
    assertTrue(joinColumns[0].insertable());
    assertTrue(joinColumns[0].updatable());
    assertTrue(joinColumns[0].nullable());
    assertFalse(joinColumns[0].unique());
    assertEquals("col1", joinColumns[1].name());
    assertEquals("col2", joinColumns[1].referencedColumnName());
    assertEquals("table1", joinColumns[1].table());
    assertEquals("int", joinColumns[1].columnDefinition());
    assertFalse(joinColumns[1].insertable());
    assertFalse(joinColumns[1].updatable());
    assertFalse(joinColumns[1].nullable());
    assertTrue(joinColumns[1].unique());
}
Also used : MapKeyJoinColumn(jakarta.persistence.MapKeyJoinColumn) JoinColumn(jakarta.persistence.JoinColumn) JoinColumns(jakarta.persistence.JoinColumns) MapKeyJoinColumns(jakarta.persistence.MapKeyJoinColumns) Test(org.junit.Test)

Example 7 with JoinColumns

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

the class Ejb3XmlOneToOneTest method testMultipleJoinColumns.

@Test
public void testMultipleJoinColumns() throws Exception {
    reader = getReader(Entity1.class, "field1", "one-to-one.orm5.xml");
    assertAnnotationPresent(OneToOne.class);
    assertAnnotationNotPresent(PrimaryKeyJoinColumn.class);
    assertAnnotationNotPresent(PrimaryKeyJoinColumns.class);
    assertAnnotationNotPresent(JoinColumn.class);
    assertAnnotationPresent(JoinColumns.class);
    assertAnnotationNotPresent(JoinTable.class);
    JoinColumns joinColumnsAnno = reader.getAnnotation(JoinColumns.class);
    JoinColumn[] joinColumns = joinColumnsAnno.value();
    assertEquals(2, joinColumns.length);
    assertEquals("", joinColumns[0].name());
    assertEquals("", joinColumns[0].referencedColumnName());
    assertEquals("", joinColumns[0].table());
    assertEquals("", joinColumns[0].columnDefinition());
    assertTrue(joinColumns[0].insertable());
    assertTrue(joinColumns[0].updatable());
    assertTrue(joinColumns[0].nullable());
    assertFalse(joinColumns[0].unique());
    assertEquals("col1", joinColumns[1].name());
    assertEquals("col2", joinColumns[1].referencedColumnName());
    assertEquals("table1", joinColumns[1].table());
    assertEquals("int", joinColumns[1].columnDefinition());
    assertFalse(joinColumns[1].insertable());
    assertFalse(joinColumns[1].updatable());
    assertFalse(joinColumns[1].nullable());
    assertTrue(joinColumns[1].unique());
}
Also used : JoinColumn(jakarta.persistence.JoinColumn) PrimaryKeyJoinColumn(jakarta.persistence.PrimaryKeyJoinColumn) JoinColumns(jakarta.persistence.JoinColumns) PrimaryKeyJoinColumns(jakarta.persistence.PrimaryKeyJoinColumns) Test(org.junit.Test)

Example 8 with JoinColumns

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

the class AnnotationBinder method addProperty.

private static int addProperty(PropertyContainer propertyContainer, XProperty property, List<PropertyData> inFlightPropertyDataList, MetadataBuildingContext context) {
    // and if so, skip it..
    for (PropertyData propertyData : inFlightPropertyDataList) {
        if (propertyData.getPropertyName().equals(property.getName())) {
            Id incomingIdProperty = property.getAnnotation(Id.class);
            Id existingIdProperty = propertyData.getProperty().getAnnotation(Id.class);
            if (incomingIdProperty != null && existingIdProperty == null) {
                throw new MappingException(String.format("You cannot override the [%s] non-identifier property from the [%s] base class or @MappedSuperclass and make it an identifier in the [%s] subclass!", propertyData.getProperty().getName(), propertyData.getProperty().getDeclaringClass().getName(), property.getDeclaringClass().getName()));
            }
            // EARLY EXIT!!!
            return 0;
        }
    }
    final XClass declaringClass = propertyContainer.getDeclaringClass();
    final XClass entity = propertyContainer.getEntityAtStake();
    int idPropertyCounter = 0;
    PropertyData propertyAnnotatedElement = new PropertyInferredData(declaringClass, property, propertyContainer.getClassLevelAccessType().getType(), context.getBootstrapContext().getReflectionManager());
    /*
		 * put element annotated by @Id in front
		 * since it has to be parsed before any association by Hibernate
		 */
    final XAnnotatedElement element = propertyAnnotatedElement.getProperty();
    if (hasIdAnnotation(element)) {
        inFlightPropertyDataList.add(0, propertyAnnotatedElement);
        /*
			 * The property must be put in hibernate.properties as it's a system wide property. Fixable?
			 * TODO support true/false/default on the property instead of present / not present
			 * TODO is @Column mandatory?
			 * TODO add method support
			 */
        if (context.getBuildingOptions().isSpecjProprietarySyntaxEnabled()) {
            if (element.isAnnotationPresent(Id.class) && element.isAnnotationPresent(Column.class)) {
                String columnName = element.getAnnotation(Column.class).name();
                for (XProperty prop : declaringClass.getDeclaredProperties(AccessType.FIELD.getType())) {
                    if (!prop.isAnnotationPresent(MapsId.class)) {
                        /*
							 * The detection of a configured individual JoinColumn differs between Annotation
							 * and XML configuration processing.
							 */
                        boolean isRequiredAnnotationPresent = false;
                        JoinColumns groupAnnotation = prop.getAnnotation(JoinColumns.class);
                        if ((prop.isAnnotationPresent(JoinColumn.class) && prop.getAnnotation(JoinColumn.class).name().equals(columnName))) {
                            isRequiredAnnotationPresent = true;
                        } else if (prop.isAnnotationPresent(JoinColumns.class)) {
                            for (JoinColumn columnAnnotation : groupAnnotation.value()) {
                                if (columnName.equals(columnAnnotation.name())) {
                                    isRequiredAnnotationPresent = true;
                                    break;
                                }
                            }
                        }
                        if (isRequiredAnnotationPresent) {
                            // create a PropertyData for the specJ property holding the mapping
                            PropertyData specJPropertyData = new PropertyInferredData(declaringClass, // same dec
                            prop, // the actual @XToOne property
                            propertyContainer.getClassLevelAccessType().getType(), // TODO we should get the right accessor but the same as id would do
                            context.getBootstrapContext().getReflectionManager());
                            context.getMetadataCollector().addPropertyAnnotatedWithMapsIdSpecj(entity, specJPropertyData, element.toString());
                        }
                    }
                }
            }
        }
        if (hasToOneAnnotation(element)) {
            context.getMetadataCollector().addToOneAndIdProperty(entity, propertyAnnotatedElement);
        }
        idPropertyCounter++;
    } else {
        inFlightPropertyDataList.add(propertyAnnotatedElement);
    }
    if (element.isAnnotationPresent(MapsId.class)) {
        context.getMetadataCollector().addPropertyAnnotatedWithMapsId(entity, propertyAnnotatedElement);
    }
    return idPropertyCounter;
}
Also used : BinderHelper.getPropertyOverriddenByMapperOrMapsId(org.hibernate.cfg.BinderHelper.getPropertyOverriddenByMapperOrMapsId) MapsId(jakarta.persistence.MapsId) XProperty(org.hibernate.annotations.common.reflection.XProperty) AnnotatedJoinColumn.buildJoinTableJoinColumns(org.hibernate.cfg.AnnotatedJoinColumn.buildJoinTableJoinColumns) JoinColumns(jakarta.persistence.JoinColumns) PrimaryKeyJoinColumns(jakarta.persistence.PrimaryKeyJoinColumns) MapKeyJoinColumns(jakarta.persistence.MapKeyJoinColumns) XAnnotatedElement(org.hibernate.annotations.common.reflection.XAnnotatedElement) XClass(org.hibernate.annotations.common.reflection.XClass) UniqueConstraint(jakarta.persistence.UniqueConstraint) Constraint(org.hibernate.mapping.Constraint) MappingException(org.hibernate.MappingException) MapKeyJoinColumn(jakarta.persistence.MapKeyJoinColumn) JoinColumn(jakarta.persistence.JoinColumn) PrimaryKeyJoinColumn(jakarta.persistence.PrimaryKeyJoinColumn) MapKeyColumn(jakarta.persistence.MapKeyColumn) MapKeyJoinColumn(jakarta.persistence.MapKeyJoinColumn) JoinColumn(jakarta.persistence.JoinColumn) Column(jakarta.persistence.Column) PrimaryKeyJoinColumn(jakarta.persistence.PrimaryKeyJoinColumn) OrderColumn(jakarta.persistence.OrderColumn) DiscriminatorColumn(jakarta.persistence.DiscriminatorColumn) AnnotatedDiscriminatorColumn.buildDiscriminatorColumn(org.hibernate.cfg.AnnotatedDiscriminatorColumn.buildDiscriminatorColumn) BinderHelper.getPropertyOverriddenByMapperOrMapsId(org.hibernate.cfg.BinderHelper.getPropertyOverriddenByMapperOrMapsId) Id(jakarta.persistence.Id) NaturalId(org.hibernate.annotations.NaturalId) EmbeddedId(jakarta.persistence.EmbeddedId) MapsId(jakarta.persistence.MapsId) CollectionId(org.hibernate.annotations.CollectionId)

Example 9 with JoinColumns

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

the class AnnotationBinder method bindOneToOne.

private static void bindOneToOne(PropertyHolder propertyHolder, PropertyData inferredData, boolean isIdentifierMapper, boolean inSecondPass, MetadataBuildingContext context, XProperty property, AnnotatedJoinColumn[] joinColumns, PropertyBinder propertyBinder, boolean forcePersist) {
    OneToOne ann = property.getAnnotation(OneToOne.class);
    // check validity
    if (property.isAnnotationPresent(Column.class) || property.isAnnotationPresent(Columns.class)) {
        throw new AnnotationException("@Column(s) not allowed on a @OneToOne property: " + BinderHelper.getPath(propertyHolder, inferredData));
    }
    // FIXME support a proper PKJCs
    boolean trueOneToOne = property.isAnnotationPresent(PrimaryKeyJoinColumn.class) || property.isAnnotationPresent(PrimaryKeyJoinColumns.class);
    Cascade hibernateCascade = property.getAnnotation(Cascade.class);
    NotFound notFound = property.getAnnotation(NotFound.class);
    boolean ignoreNotFound = notFound != null && notFound.action() == NotFoundAction.IGNORE;
    // MapsId means the columns belong to the pk;
    // A @MapsId association (obviously) must be non-null when the entity is first persisted.
    // If a @MapsId association is not mapped with @NotFound(IGNORE), then the association
    // is mandatory (even if the association has optional=true).
    // If a @MapsId association has optional=true and is mapped with @NotFound(IGNORE) then
    // the association is optional.
    // @OneToOne(optional = true) with @PKJC makes the association optional.
    final boolean mandatory = !ann.optional() || property.isAnnotationPresent(Id.class) || property.isAnnotationPresent(MapsId.class) && !ignoreNotFound;
    matchIgnoreNotFoundWithFetchType(propertyHolder.getEntityName(), property.getName(), ignoreNotFound, ann.fetch());
    OnDelete onDeleteAnn = property.getAnnotation(OnDelete.class);
    JoinTable assocTable = propertyHolder.getJoinTable(property);
    if (assocTable != null) {
        Join join = propertyHolder.addJoin(assocTable, false);
        for (AnnotatedJoinColumn joinColumn : joinColumns) {
            joinColumn.setExplicitTableName(join.getTable().getName());
        }
    }
    bindOneToOne(getCascadeStrategy(ann.cascade(), hibernateCascade, ann.orphanRemoval(), forcePersist), joinColumns, !mandatory, getFetchMode(ann.fetch()), ignoreNotFound, onDeleteAnn != null && OnDeleteAction.CASCADE == onDeleteAnn.action(), ToOneBinder.getTargetEntity(inferredData, context), propertyHolder, inferredData, ann.mappedBy(), trueOneToOne, isIdentifierMapper, inSecondPass, propertyBinder, context);
}
Also used : AnnotatedJoinColumn.buildJoinTableJoinColumns(org.hibernate.cfg.AnnotatedJoinColumn.buildJoinTableJoinColumns) JoinColumns(jakarta.persistence.JoinColumns) PrimaryKeyJoinColumns(jakarta.persistence.PrimaryKeyJoinColumns) Columns(org.hibernate.annotations.Columns) MapKeyJoinColumns(jakarta.persistence.MapKeyJoinColumns) Join(org.hibernate.mapping.Join) OneToOne(jakarta.persistence.OneToOne) PrimaryKeyJoinColumn(jakarta.persistence.PrimaryKeyJoinColumn) PrimaryKeyJoinColumns(jakarta.persistence.PrimaryKeyJoinColumns) MapKeyColumn(jakarta.persistence.MapKeyColumn) MapKeyJoinColumn(jakarta.persistence.MapKeyJoinColumn) JoinColumn(jakarta.persistence.JoinColumn) Column(jakarta.persistence.Column) PrimaryKeyJoinColumn(jakarta.persistence.PrimaryKeyJoinColumn) OrderColumn(jakarta.persistence.OrderColumn) DiscriminatorColumn(jakarta.persistence.DiscriminatorColumn) AnnotatedDiscriminatorColumn.buildDiscriminatorColumn(org.hibernate.cfg.AnnotatedDiscriminatorColumn.buildDiscriminatorColumn) AnnotationException(org.hibernate.AnnotationException) Cascade(org.hibernate.annotations.Cascade) NotFound(org.hibernate.annotations.NotFound) OnDelete(org.hibernate.annotations.OnDelete) JoinTable(jakarta.persistence.JoinTable)

Example 10 with JoinColumns

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

the class AnnotationBinder method bindManyToOne.

private static void bindManyToOne(String cascadeStrategy, AnnotatedJoinColumn[] columns, boolean optional, boolean ignoreNotFound, boolean cascadeOnDelete, XClass targetEntity, PropertyHolder propertyHolder, PropertyData inferredData, boolean unique, boolean isIdentifierMapper, boolean inSecondPass, PropertyBinder propertyBinder, MetadataBuildingContext context) {
    // All FK columns should be in the same table
    org.hibernate.mapping.ManyToOne value = new org.hibernate.mapping.ManyToOne(context, columns[0].getTable());
    // This is a @OneToOne mapped to a physical o.h.mapping.ManyToOne
    if (unique) {
        value.markAsLogicalOneToOne();
    }
    value.setReferencedEntityName(ToOneBinder.getReferenceEntityName(inferredData, targetEntity, context));
    final XProperty property = inferredData.getProperty();
    defineFetchingStrategy(value, property);
    // value.setFetchMode( fetchMode );
    value.setIgnoreNotFound(ignoreNotFound);
    value.setCascadeDeleteEnabled(cascadeOnDelete);
    // value.setLazy( fetchMode != FetchMode.JOIN );
    if (!optional) {
        for (AnnotatedJoinColumn column : columns) {
            column.setNullable(false);
        }
    }
    if (property.isAnnotationPresent(MapsId.class)) {
        // read only
        for (AnnotatedJoinColumn column : columns) {
            column.setInsertable(false);
            column.setUpdatable(false);
        }
    }
    final JoinColumn joinColumn = property.getAnnotation(JoinColumn.class);
    final JoinColumns joinColumns = property.getAnnotation(JoinColumns.class);
    // Make sure that JPA1 key-many-to-one columns are read only too
    boolean hasSpecjManyToOne = false;
    if (context.getBuildingOptions().isSpecjProprietarySyntaxEnabled()) {
        String columnName = "";
        for (XProperty prop : inferredData.getDeclaringClass().getDeclaredProperties(AccessType.FIELD.getType())) {
            if (prop.isAnnotationPresent(Id.class) && prop.isAnnotationPresent(Column.class)) {
                columnName = prop.getAnnotation(Column.class).name();
            }
            if (property.isAnnotationPresent(ManyToOne.class) && joinColumn != null && !BinderHelper.isEmptyAnnotationValue(joinColumn.name()) && joinColumn.name().equals(columnName) && !property.isAnnotationPresent(MapsId.class)) {
                hasSpecjManyToOne = true;
                for (AnnotatedJoinColumn column : columns) {
                    column.setInsertable(false);
                    column.setUpdatable(false);
                }
            }
        }
    }
    value.setTypeName(inferredData.getClassOrElementName());
    final String propertyName = inferredData.getPropertyName();
    value.setTypeUsingReflection(propertyHolder.getClassName(), propertyName);
    bindForeignKeyNameAndDefinition(value, property, propertyHolder.getOverriddenForeignKey(StringHelper.qualify(propertyHolder.getPath(), propertyName)), joinColumn, joinColumns, context);
    String path = propertyHolder.getPath() + "." + propertyName;
    FkSecondPass secondPass = new ToOneFkSecondPass(value, columns, // cannot have nullable and unique on certain DBs like Derby
    !optional && unique, propertyHolder.getEntityOwnerClassName(), path, context);
    if (inSecondPass) {
        secondPass.doSecondPass(context.getMetadataCollector().getEntityBindingMap());
    } else {
        context.getMetadataCollector().addSecondPass(secondPass);
    }
    AnnotatedColumn.checkPropertyConsistency(columns, propertyHolder.getEntityName() + "." + propertyName);
    // PropertyBinder binder = new PropertyBinder();
    propertyBinder.setName(propertyName);
    propertyBinder.setValue(value);
    // binder.setCascade(cascadeStrategy);
    if (isIdentifierMapper) {
        propertyBinder.setInsertable(false);
        propertyBinder.setUpdatable(false);
    } else if (hasSpecjManyToOne) {
        propertyBinder.setInsertable(false);
        propertyBinder.setUpdatable(false);
    } else {
        propertyBinder.setInsertable(columns[0].isInsertable());
        propertyBinder.setUpdatable(columns[0].isUpdatable());
    }
    propertyBinder.setColumns(columns);
    propertyBinder.setAccessType(inferredData.getDefaultAccess());
    propertyBinder.setCascade(cascadeStrategy);
    propertyBinder.setProperty(property);
    propertyBinder.setXToMany(true);
    final Property boundProperty = propertyBinder.makePropertyAndBind();
    if (joinColumn != null) {
        boundProperty.setOptional(joinColumn.nullable() && optional);
    } else {
        boundProperty.setOptional(optional);
    }
}
Also used : XProperty(org.hibernate.annotations.common.reflection.XProperty) AnnotatedJoinColumn.buildJoinTableJoinColumns(org.hibernate.cfg.AnnotatedJoinColumn.buildJoinTableJoinColumns) JoinColumns(jakarta.persistence.JoinColumns) PrimaryKeyJoinColumns(jakarta.persistence.PrimaryKeyJoinColumns) MapKeyJoinColumns(jakarta.persistence.MapKeyJoinColumns) ManyToOne(jakarta.persistence.ManyToOne) MapKeyJoinColumn(jakarta.persistence.MapKeyJoinColumn) JoinColumn(jakarta.persistence.JoinColumn) PrimaryKeyJoinColumn(jakarta.persistence.PrimaryKeyJoinColumn) MapKeyColumn(jakarta.persistence.MapKeyColumn) MapKeyJoinColumn(jakarta.persistence.MapKeyJoinColumn) JoinColumn(jakarta.persistence.JoinColumn) Column(jakarta.persistence.Column) PrimaryKeyJoinColumn(jakarta.persistence.PrimaryKeyJoinColumn) OrderColumn(jakarta.persistence.OrderColumn) DiscriminatorColumn(jakarta.persistence.DiscriminatorColumn) AnnotatedDiscriminatorColumn.buildDiscriminatorColumn(org.hibernate.cfg.AnnotatedDiscriminatorColumn.buildDiscriminatorColumn) BinderHelper.getPropertyOverriddenByMapperOrMapsId(org.hibernate.cfg.BinderHelper.getPropertyOverriddenByMapperOrMapsId) Id(jakarta.persistence.Id) NaturalId(org.hibernate.annotations.NaturalId) EmbeddedId(jakarta.persistence.EmbeddedId) MapsId(jakarta.persistence.MapsId) CollectionId(org.hibernate.annotations.CollectionId) Property(org.hibernate.mapping.Property) XProperty(org.hibernate.annotations.common.reflection.XProperty)

Aggregations

JoinColumns (jakarta.persistence.JoinColumns)15 JoinColumn (jakarta.persistence.JoinColumn)14 MapKeyJoinColumn (jakarta.persistence.MapKeyJoinColumn)8 MapKeyJoinColumns (jakarta.persistence.MapKeyJoinColumns)8 PrimaryKeyJoinColumn (jakarta.persistence.PrimaryKeyJoinColumn)8 PrimaryKeyJoinColumns (jakarta.persistence.PrimaryKeyJoinColumns)8 AnnotationException (org.hibernate.AnnotationException)6 Test (org.junit.Test)6 OrderColumn (jakarta.persistence.OrderColumn)5 AnnotatedJoinColumn.buildJoinTableJoinColumns (org.hibernate.cfg.AnnotatedJoinColumn.buildJoinTableJoinColumns)5 Column (jakarta.persistence.Column)4 DiscriminatorColumn (jakarta.persistence.DiscriminatorColumn)4 MapKeyColumn (jakarta.persistence.MapKeyColumn)4 Columns (org.hibernate.annotations.Columns)4 JoinTable (jakarta.persistence.JoinTable)3 ManyToOne (jakarta.persistence.ManyToOne)3 OneToMany (jakarta.persistence.OneToMany)3 Cascade (org.hibernate.annotations.Cascade)3 Comment (org.hibernate.annotations.Comment)3 NotFound (org.hibernate.annotations.NotFound)3