Hi,
In our information system, we have encoded roles to save space and also to be able to rename or move the relevant classes (not having the Java model in the database).
Example :
It’s silimary to :
@AnyDiscriminatorValue(discriminator = "AA", entity = Agent.class)
We cannot use @AnyDiscriminatorValue
if we want to use DefaultDiscriminatorConverter
to reference many entities. Also, if the entity is not known from the library, this poses a second problem.
One solution is to use DefaultDiscriminatorConverter
and convert the entity name into a hashcode. However, there is no possibility to override DiscriminatedAssociationAttributeMapping
, so I have to duplicate a bit of code to achieve this.
JavaRoleMapUtil
is us process for hashcode the role.- Override to
DiscriminatedAssociationAttributeMapping
for useJavaRoleMapUtil
public class EfluidDiscriminatedAssociationAttributeMapping extends DiscriminatedAssociationAttributeMapping {
public EfluidDiscriminatedAssociationAttributeMapping(NavigableRole attributeRole, JavaType<?> baseAssociationJtd,
ManagedMappingType declaringType, int stateArrayPosition, int fetchableIndex, AttributeMetadata attributeMetadata,
FetchTiming fetchTiming, PropertyAccess propertyAccess, Property bootProperty, AnyType anyType,
Any bootValueMapping, MappingModelCreationProcess creationProcess) {
super(attributeRole, baseAssociationJtd, declaringType, stateArrayPosition, fetchableIndex, attributeMetadata, fetchTiming, propertyAccess, bootProperty, anyType, bootValueMapping, creationProcess);
}
@Override
public EntityMappingType resolveDiscriminatorValue(Object discriminatorValue) {
try {
return super.resolveDiscriminatorValue(discriminatorValue);
} catch (HibernateException ex) {
if (discriminatorValue instanceof String s) {
return super.resolveDiscriminatorValue(JavaRoleMapUtil.fromHashCode(s));
}
throw ex;
}
}
@Override
public Object resolveDiscriminatorForEntityType(EntityMappingType entityMappingType) {
Object object = super.resolveDiscriminatorForEntityType(entityMappingType);
if (object instanceof String s) {
return Optional.ofNullable(JavaRoleMapUtil.toHashCode(s)).orElse(s);
}
return object;
}
}
- The code duplicated for use
EfluidDiscriminatedAssociationAttributeMapping
:
public class EfluidSingleTableEntityPersister extends SingleTableEntityPersister {
public EfluidSingleTableEntityPersister(PersistentClass persistentClass, EntityDataAccess cacheAccessStrategy, NaturalIdDataAccess naturalIdRegionAccessStrategy, PersisterCreationContext creationContext) throws HibernateException {
super(persistentClass, cacheAccessStrategy, naturalIdRegionAccessStrategy, creationContext);
}
/**
* Cette surcharge permet de gérer le {@link com.hermes.arc.commun.util.JavaRoleMapUtil} pour les relations @{@link Any}.
*/
@Override
protected AttributeMapping generateNonIdAttributeMapping(NonIdentifierAttribute tupleAttrDefinition, Property bootProperty, int stateArrayPosition, int fetchableIndex, MappingModelCreationProcess creationProcess) {
final Type attrType = tupleAttrDefinition.getType();
if (attrType instanceof AnyType) {
return getDiscriminatedAssociationAttributeMapping(bootProperty, stateArrayPosition, fetchableIndex, creationProcess, (AnyType) attrType);
} else {
return super.generateNonIdAttributeMapping(tupleAttrDefinition, bootProperty, stateArrayPosition, fetchableIndex, creationProcess);
}
}
/**
* Code dupliqué de {@link org.hibernate.persister.entity.AbstractEntityPersister#generateNonIdAttributeMapping} pour la partie AnyType.
* Aucune autre modification que l'utilisation de {@link EfluidDiscriminatedAssociationAttributeMapping}.
*/
private DiscriminatedAssociationAttributeMapping getDiscriminatedAssociationAttributeMapping(final Property bootProperty, final int stateArrayPosition, final int fetchableIndex, final MappingModelCreationProcess creationProcess, final AnyType attrType) {
PropertyAccess propertyAccess = getRepresentationStrategy().resolvePropertyAccess(bootProperty);
RuntimeModelCreationContext creationContext = creationProcess.getCreationContext();
Value value = bootProperty.getValue();
JavaType<Object> baseAssociationJtd = creationContext.getTypeConfiguration().getJavaTypeRegistry().getDescriptor(Object.class);
MutabilityPlan<?> mutabilityPlan = new DiscriminatedAssociationAttributeMapping.MutabilityPlanImpl(attrType);
SimpleAttributeMetadata attributeMetadataAccess = new SimpleAttributeMetadata(propertyAccess, mutabilityPlan, bootProperty.isOptional(), bootProperty.isInsertable(), bootProperty.isUpdateable(), bootProperty.isOptimisticLocked(), bootProperty.isSelectable());
return new EfluidDiscriminatedAssociationAttributeMapping(getNavigableRole().append(bootProperty.getName()), baseAssociationJtd, this, stateArrayPosition, fetchableIndex, attributeMetadataAccess, bootProperty.isLazy() ? FetchTiming.DELAYED : FetchTiming.IMMEDIATE, propertyAccess, bootProperty, attrType, (Any) value, creationProcess);
}
}