The mapping [itemId] from the embedded ID class [class example.ItemInventoryCompositeKey] is an invalid mapping for this class

Hi,

It seems the problem still exist with the latest Cuba version. I tried to use composite key following the example mentioned in the start of this thread, I am getting the error:

> Caused by: Exception [EclipseLink-7298] (Eclipse Persistence Services - 2.7.3.6-cuba): org.eclipse.persistence.exceptions.ValidationException
> Exception Description: The mapping [itemId] from the embedded ID class [class example.ItemInventoryCompositeKey] is an invalid mapping for this class. An embeddable class that is used with an embedded ID specification (attribute [itemInventoryCompositeKey] from the source [class example.ItemInventory]) can only contain basic mappings. Either remove the non basic mapping or change the embedded ID specification on the source to be embedded.
> 	at org.eclipse.persistence.exceptions.ValidationException.invalidMappingForEmbeddedId(ValidationException.java:1312)
> 	at org.eclipse.persistence.internal.jpa.metadata.accessors.mappings.EmbeddedIdAccessor.addIdFieldsFromAccessors(EmbeddedIdAccessor.java:152)
> 	at org.eclipse.persistence.internal.jpa.metadata.accessors.mappings.EmbeddedIdAccessor.process(EmbeddedIdAccessor.java:195)
> 	at org.eclipse.persistence.internal.jpa.metadata.MetadataDescriptor.processMappingAccessors(MetadataDescriptor.java:1525)
> 	at org.eclipse.persistence.internal.jpa.metadata.accessors.classes.ClassAccessor.processMappingAccessors(ClassAccessor.java:1658)
> 	at org.eclipse.persistence.internal.jpa.metadata.accessors.classes.EntityAccessor.processMappingAccessors(EntityAccessor.java:1242)
> 	at org.eclipse.persistence.internal.jpa.metadata.accessors.classes.EntityAccessor.process(EntityAccessor.java:701)
> 	at org.eclipse.persistence.internal.jpa.metadata.MetadataProject.processStage2(MetadataProject.java:1879)
> 	at org.eclipse.persistence.internal.jpa.metadata.MetadataProcessor.processORMMetadata(MetadataProcessor.java:580)
> 	at org.eclipse.persistence.internal.jpa.deployment.PersistenceUnitProcessor.processORMetadata(PersistenceUnitProcessor.java:629)
> 	at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.predeploy(EntityManagerSetupImpl.java:2001)
> 	... 6 more

Any idea how to solve this problem?

Hi,
Unfortunately, there is no simple way to use association attributes in composite PK, as EclipseLink does not support it.

But you can work around the problem as follows:

Let’s suppose Entity_1 has a composite PK.
The PK is presented by KeyEntity (EmbeddableEntity). It was created by CUBA Studio and has a link to Entity_2.

  1. In the “KeyEntity” modify the link field: make it of basic type instead of @ManyToOne.
public class KeyEntity extends EmbeddableEntity {
...
    @Column(name = "ENTITY2LINK_ID")
    protected Integer entity2link; //Entity_2 has Integer Id
...
  1. Then in the Entity_1 create the property entity_2 mark it with @Transient and @MetaProperty, and define its get/set methods similar to following.
....
@EmbeddedId
protected KeyEntity id;

@Transient
@MetaProperty
protected Entity_2 entity_2;

 public Entity_2 getEntity_2() {
        if (entity_2 == null && id.getEntity2link() != null) {
            DataManager dm = AppBeans.get(DataManager.class);
            entity_2 = dm.load(LoadContext
                    .create(Entity_2.class)
                    .setId(id.getEntity2link()));
        }
        return entity_2;
    }

    public void setEntity_2(Entity_2 entity_2) {
        this.id.setEntity2link(entity_2.getId());
        this.entity_2 = entity_2;
    }

This should work.

Regards.

1 Like

Hi,

Thanks for the suggestion.

With a composite key of 4 different objects that are not primitives (i.e. integer), the workaround starts to be quite complex (and ugly - please don’t take this personally).

I am trying to find a workaround from the data modelling perspective. If there are any ideas, please share.

Thanks,