I’m trying to implement a TypeBridge for a transient object. The object implements Map and has arbitrary keys.
I feel like I’m missing some important piece of context, and am coming across errors that don’t make sense to me.
@TypeBinding(binder = TypeBinderRef(type = ProductAttributesTypeBinder::class))
class ProductAttributes(val product: Product) : MutableMap<String, Any?> by product._attributes {
val changes = mutableMapOf<String, Any?>();
protected val types: Map<String, BaseAttributeType<Any?>> by lazy {
product.family.attributes.fold(mutableMapOf<String, BaseAttributeType<Any?>>(), { acc, attr ->
acc[attr.code!!] = attr.type!! as BaseAttributeType<Any?>
acc
})
}
override fun put(key: String, value: Any?): Any? {
val v = product._attributes[key]
val type = types[key] ?: throw InvalidAttributeException("`$key` is not a valid attribute on this product")
type.validate(value)
product._attributes[key] = value
this.changes[key] = value
return v
}
override fun get(key: String): Any? {
return product._attributes[key]
}
}
@Entity
@Indexed
@TypeDefs(TypeDef(name = "jsonb", typeClass = JsonBinaryType::class))
open class Product protected constructor() {
@Id
@GeneratedValue
var id: Long? = null
// ...
@Transient
// @PropertyBinding(binder = PropertyBinderRef(type = ProductAttributesBinder::class))
@IndexedEmbedded(targetType = ProductAttributes::class)
val attributes = ProductAttributes(this)
// ...
}
class ProductAttributesTypeBinder : TypeBinder {
override fun bind(context: TypeBindingContext) {
// context.dependencies().use(PojoModelPath.builder().property( "product" ).property("_attributes").toValuePath())
context.dependencies().use("product._attributes")
// context.dependencies().useRootOnly()
val attributesField = context.indexSchemaElement().objectField("attributes")
attributesField.fieldTemplate("attributes_string") { f -> f.asString().analyzer("default")}
context.setBridge(ProductAttributesTypeBridge(attributesField.toReference()))
}
}
class ProductAttributesTypeBridge(val fieldReference: IndexObjectFieldReference) : TypeBridge {
override fun write(target: DocumentElement, bridgedElement: Any, context: TypeBridgeWriteContext) {
val attributes = bridgedElement as ProductAttributes
val indexedAttributes: DocumentElement = target.addObject(fieldReference)
attributes.entries.forEach {
indexedAttributes.addValue(it.key, it.value)
}
}
}
No matter how I try to implement this, I get errors like the below. Any suggestions on how to start with indexing the attributes property? I eventually want to all the attribute types to control the way the attribute values are indexed.
Caused by: org.hibernate.search.util.common.SearchException: HSEARCH000520: Hibernate Search encountered failures during bootstrap. Failures:
Hibernate ORM mapping:
type 'com.tradetested.pim.domain.catalog.Product':
path '.attributes<map-value>':
failures:
- HSEARCH800010: Unable to find a readable property 'product' on type 'java.lang.Object'.
at org.hibernate.search.engine.reporting.spi.RootFailureCollector.checkNoFailure(RootFailureCollector.java:50)
at org.hibernate.search.engine.common.impl.SearchIntegrationBuilderImpl.prepareBuild(SearchIntegrationBuilderImpl.java:259)
at org.hibernate.search.mapper.orm.bootstrap.impl.HibernateOrmIntegrationBooterImpl.doBootFirstPhase(HibernateOrmIntegrationBooterImpl.java:250)
at org.hibernate.search.mapper.orm.bootstrap.impl.HibernateOrmIntegrationBooterImpl.preBoot(HibernateOrmIntegrationBooterImpl.java:128)
at io.quarkus.hibernate.search.elasticsearch.runtime.HibernateSearchElasticsearchRecorder$HibernateSearchIntegrationListener.onMetadataInitialized(HibernateSearchElasticsearchRecorder.java:85)
at io.quarkus.hibernate.orm.runtime.integration.HibernateOrmIntegrations.onMetadataInitialized(HibernateOrmIntegrations.java:27)
at io.quarkus.hibernate.orm.runtime.boot.FastBootMetadataBuilder.build(FastBootMetadataBuilder.java:306)
at io.quarkus.hibernate.orm.runtime.PersistenceUnitsHolder.createMetadata(PersistenceUnitsHolder.java:101)
at io.quarkus.hibernate.orm.runtime.PersistenceUnitsHolder.constructMetadataAdvance(PersistenceUnitsHolder.java:73)
at io.quarkus.hibernate.orm.runtime.PersistenceUnitsHolder.initializeJpa(PersistenceUnitsHolder.java:40)
at io.quarkus.hibernate.orm.runtime.HibernateOrmRecorder$4.created(HibernateOrmRecorder.java:88)
at io.quarkus.arc.runtime.ArcRecorder.initBeanContainer(ArcRecorder.java:106)
at io.quarkus.deployment.steps.ArcProcessor$generateResources-1120260799.deploy_0(ArcProcessor$generateResources-1120260799.zig:520)
at io.quarkus.deployment.steps.ArcProcessor$generateResources-1120260799.deploy(ArcProcessor$generateResources-1120260799.zig:36)
at io.quarkus.runner.ApplicationImpl.<clinit>(ApplicationImpl.zig:160)
... 66 more