Hi Otavio,
Here is my feedback about my intention to use
polymorphism with jnosql.
I have my nosql entities annotated with both jakarta
nosql and jsonb annotations like.
@Column("measurementValue")
@Convert(MeasurementValueConverter.class)
@JsonbTypeDeserializer(MeasurementValueDeserializer.class)
private MeasurementValueEntity measurementValue;
1. My first question is:
Unlike implementing ValueReader / ValueWriter using
@Convert requires implementing both serialization /
deserialization.
I don't want / need to interfere in writing here, is there
a way to do this?
2. The EntityConverter class is abstract and not easy to
use from external code.
Here is my solution that is kinda awkward...
public class MeasurementValueConverter2 extends
EntityConverter
implements EntitiesMetadata,
AttributeConverter<MeasurementValue, Element> {
private final ReflectionClassConverter converter = new
ReflectionClassConverter();
private final Map<Class<?>,
EntityMetadata> classes = new ConcurrentHashMap();
public MeasurementValueConverter2() {
classes.put(QuantityEntity.class,
converter.apply(QuantityEntity.class));
// more polymorphic classes
}
@Override
public MeasurementValue
convertToEntityAttribute(Element e) {
// decide concrete class (e.g. QuantityEntity)
return toEntity(QuantityEntity.class,
e.get(List.class));
}
... many methods from EntityConverter &
EntitiesMetadata
It would be great to provide easier way to use the
converter...
Finally I went with other, dubious solution.
I already have MeasurementValueDeserializer.class JAXB
deserializer which converts JsonObject into the entity:
final JsonObject obj = value.asJsonObject();
if (obj.containsKey(("typedQuantities"))) {
return jsonb.fromJson(value.toString(),
ComplexValueEntity.class);
}
if (obj.containsKey(("id"))) {
return jsonb.fromJson(value.toString(),
OntologyTermValueEntity.class);
}
if (obj.containsKey(("unit"))) {
return jsonb.fromJson(value.toString(),
QuantityEntity.class);
}
So much easily is to reuse JSONB:
@Override
public MeasurementValue convertToEntityAttribute(Element
e) {
final JsonValue value =
JsonTypeReferenceReader.convert(e);
if (value != null) {
try {
return jsonb.fromJson(value.toString(),
MeasurementValueEntity.class);
But I need a TypeReferenceReader which converts Element
to the JsonObject.
Note, that in my project I need it anyway, because we
have some "info" field which may be ANY Json...
Here I went another adventure... My
JsonTypeReferenceReader implementation may read any
JsonValue
@Column("info")
public JsonObject info;
works perfectly, but
@Column("info")
public JsonString info;
never calls the JsonTypeReferenceReader!!!
This happens because the value "string" is a primitive and
jnosql internals only look into the Value Readers!
@Column("info")
public JsonArray info;
Fails miserably, because JsonArray implements a List so
it just considered a collection!
Another (IMHO) strange thing is that the converter is
initialized each time the converter happens:
"The converter type: class
es.bsc.inb.ga4gh.beacon.nosql.converter.MeasurementValueConverter
not found on CDI context, creating by constructor"
So the conclusion:
Although nosql introduced @Convert annotation, its usage
for polymorphism is complicated and impossible without
using jnosql internals.
Kind regards,
Dmitry
On 7/7/2024 5:56 PM, Otavio Santana wrote:
Hey, sorry for the late reply.
I will be at home for a while, until August, after
the conference season ends.
If you wish to do it manually, I believe the
Convert annotation fits better.
I will work in a PoC on this.
Hi Otavio!
The principal problem is that standard JSONB /
JPA / JNoSQL polymorphism is not enough for some
JSON schemas.
When I have "oneOf": [], the spec. says that json
must match at most one schema.
In my particular case I have a
MeasurementValueEntity and ComplexValueEntity,
OntologyTermValueEntity and QuantityEntity that
inherit from it.
So basically I'd like to catch
MeasurementValueEntity with
MeasurementValueReader, manually decide which of
three types should be instantiated and
return it. I just see no API to do this. Something
like in JAXB: jsonb.fromJson(value,
OntologyTermValueEntity.class);
I mean - I have Object value and know the Entity
class and want create the Entity object.
Kind regards,
Dmitry
On 6/27/2024 10:00 AM, Otavio Santana wrote:
Hey Dmitry, how are you?
We are doing well and thanks for all
support and feedback, you are a great
contributor!
About having not discriminator value, could
you create a scenario?
This way, we can work together on this
solution.
Hi
all,
Great to see that spec. and implementation is
moving forward.
Especially that annotations are moving to the
spec.:
org.eclipse.jnosql.mapping.Inheritance ->
jakarta.nosql.Inheritance
Nevertheless, I have a trouble with custom
inheritance with 1.1 using
ValueReader.
The implementation has changed (was Document
and its an Element now).
Is there an elegant way to implement the
inheritance when I have no
discriminator field?
public class MeasurementValueReader implements
ValueReader {
@Override
public <T> T read(Class<T>
clazz, Object value) {
if (List.class.isInstance(value)) {
final List list =
List.class.cast(value);
if
(list.stream().filter(Entry.class::isInstance)
.anyMatch(e ->
"unit".equals(((Entry)e).name()))) {
return (QuantityEntity) ???;
}
}
How may I manually convert Object value into
the concrete
(QuantityEntity) type (I catch the
"Measurement" interface).
Thank you in advance,
Dmitry
_______________________________________________
nosql-dev mailing list
nosql-dev@xxxxxxxxxxx
To unsubscribe from this list, visit https://www.eclipse.org/mailman/listinfo/nosql-dev
--
--