Skip to content

Conversation

@yrodiere
Copy link
Member

@beikov
Copy link
Member

beikov commented Feb 27, 2025

Superseded by hibernate/hibernate-orm#9815

@beikov beikov closed this Feb 27, 2025
@JihwanByun
Copy link

JihwanByun commented Feb 27, 2025

I have identified an issue related to how @EmbeddedId entities are handled in EntityMetamodel.

When an entity contains an @EmbeddedId, its properties are processed in the following loop within the EntityMetamodel constructor:

public EntityMetamodel(PersistentClass persistentClass, EntityPersister persister, RuntimeModelCreationContext creationContext) {
   
   for (int i = 0; i < props.size(); ++i) {
       ---
       if (propertyType.isMutable() && this.propertyCheckability[i] && !(propertyType instanceof ComponentType)) { 
        mutableIndexes.set(i);
       }
   }
}

However, due to the condition !(propertyType instanceof ComponentType), properties of type ComponentType—which includes @EmbeddedId—are excluded from mutableIndexes.

This results in mutableIndexes remaining empty when processing entities with an @EmbeddedId, leading to the following issue in resolveDirtyAttributeIndexes():

public int[] resolveDirtyAttributeIndexes(Object[] currentState, Object[] previousState, String[] attributeNames, SessionImplementor session) {
      BitSet mutablePropertiesIndexes = this.entityMetamodel.getMutablePropertiesIndexes();
      int estimatedSize = attributeNames == null ? 0 : attributeNames.length + mutablePropertiesIndexes.cardinality();
      List<Integer> fields = new ArrayList(estimatedSize);
      if (estimatedSize == 0) {
            return ArrayHelper.EMPTY_INT_ARRAY;
      } else {
            int i;
            if (!mutablePropertiesIndexes.isEmpty()) {
                Type[] propertyTypes = this.entityMetamodel.getPropertyTypes();
                boolean[] propertyCheckability = this.entityMetamodel.getPropertyCheckability();

                for(i = mutablePropertiesIndexes.nextSetBit(0); i >= 0; i = mutablePropertiesIndexes.nextSetBit(i + 1)) {
                    if (this.isDirty(currentState, previousState, propertyTypes, propertyCheckability, i, session)) {
                        fields.add(i);
                 }
             }
         }

...
  return ArrayHelper.toIntArray(fields);
}

Since mutablePropertiesIndexes.isEmpty() is true, no attributes are marked as dirty, even when changes occur. As a result, fields are never added to the dirty checking list, and updates fail to be detected.

Thank you.

@yrodiere
Copy link
Member Author

@JihwanByun while the problem you're pointing out is interesting, you might want to report it somewhere else than on the PR for the reproducer of a related (but different) issue...
If you haven't already, please report this on Jira.

@JihwanByun
Copy link

Thank you for the clarification. I realize now that I misunderstood the context of this PR. I appreciate your guidance! I will report the issue on Jira instead.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants