Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [nosql-dev] Polymorthism help needed.

Hey Dmitry, I've created a solution and merged it.
Could you test this newest version?

On Mon, Aug 5, 2024 at 9:45 AM Otavio Santana <otaviopolianasantana@xxxxxxxxx> wrote:
Thanks, I've created the issue:


On Thu, Aug 1, 2024 at 3:37 PM Dmitry Repchevsky <redmitry@xxxxxxx> wrote:

Great!

I am facing another unexpected issue with the Element.

Starting from version 31 WildFly doesn't look into the jar libraries to process CDI unless the project manifest explicitly includes the module as a dependence.
I tried to convert my NoSQL entities library (jar) into the module and... the jnosql-communication-semistructured module is not exported, so Element class is not accessible.
Not critical, but one more reason to decouple Converters from the Element.

Best,

Dmitry

On 7/31/2024 12:47 PM, Otavio Santana wrote:
Thanks for the advice! 
I will work on it.

On Wed, Jul 31, 2024 at 11:17 AM Dmitry Repchevsky <redmitry@xxxxxxx> wrote:

Hi Otavio,

I have a Christmas wish...

Is it possible to improve jnosql (and probably document the nosql spec) so that the convertToEntityAttribute() will always receive only standard java types?

I mean that having the Element as it is now bound the EntityConverter (which is a part of the model) to the jnosql implementation.
In the EngineConverter (polymorphism demo) you convert elements to the map:

 element.get(new TypeReference<List<Element>>() {
            }).stream().collect(Collectors.toMap(Element::name, Element::get));

IMO something like this must be done BEFORE calling the convertToEntityAttribute(), so we receive a Map (with nested maps) tree structure.

Kind regards,

Dmitry

On 7/30/2024 12:31 PM, Dmitry Repchevsky wrote:

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.









On Thu, Jun 27, 2024 at 11:33 AM Dmitry Repchevsky <redmitry@xxxxxxx> wrote:

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.

On Wed, Jun 26, 2024 at 11:24 AM Dmitry Repchevsky via nosql-dev <nosql-dev@xxxxxxxxxxx> wrote:
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


--

Thanks a lot,

Twitter | Linkedin | Youtube



--

Thanks a lot,

Twitter | Linkedin | Youtube



--

Thanks a lot,

Twitter | Linkedin | Youtube



--

Thanks a lot,

Twitter | Linkedin | Youtube



--

Thanks a lot,

Twitter | Linkedin | Youtube


Back to the top