eclipse / jnosql

Eclipse JNoSQL is a framework which has the goal to help Java developers to create Jakarta EE applications with NoSQL.
Other
229 stars 72 forks source link

[BUG] There is no way to configure ArangoSerde used by ArangoDBDocumentManager #437

Closed m4ttek closed 9 months ago

m4ttek commented 1 year ago

Which JNoSQL project the issue refers to?

JNoSQL Databases

Bug description

ArangoDBDocumentConfiguration class is final what makes impossible to override protected method getArangoDB present in ArangoDBConfiguration class.

There is also no way to Inject your own ArangoDB object with custom configuration.

ArangoDBDocumentManager interface does not give possibility to get ArangoDB object also. And its implementation DefaultArangoDBDocumentManager is package private.

JNoSQL Version

1.0.1

Steps To Reproduce

Try to customize ArangoDB.Builder with your own configuration that requires programmatic settings and object creation.

Expected Results

I should be able to inject or intercept or at least override ArangoDB object creation.

Code example, screenshot, or link to a repository

No response

m4ttek commented 1 year ago

To give more context - I'd like to provide user-data serde, according to https://www.arangodb.com/docs/stable/drivers/java-reference-serialization.html#custom-serializers

otaviojava commented 1 year ago

@m4ttek thank you for those points; we will work to release in this next version.

otaviojava commented 1 year ago

I got an idea using the properties:

jnosql.arangodb.deserializer.1=the class path
jnosql.arangodb.deserializer.2=the class path
jnosql.arangodb.seserializer.1=the class path
jnosql.arangodb.seserializer.2=the class path

I will create the implementation and ask for your help to review it.

m4ttek commented 1 year ago

@otaviojava great idea!

And if it's not a problem, I'd also suggest supporting some kind of annotation for entity types like @EntitySerializer and @EntityDeserializer with required argument of a provided class type that must implement generic Serializer or Deserializer interface with proper implementation for Arango. Thus, it would be easier to exchange chosen database in any future.

otaviojava commented 1 year ago

I have the draft work here:

https://github.com/eclipse/jnosql-databases/pull/242

otaviojava commented 12 months ago

Hey @m4ttek,

Do you know about the @org.eclipse.jnosql.mapping.Convert annotation? This annotation allows developers to define field-level converters, providing a way to map custom data types between the database and Java objects.

Here's a brief explanation of how it works:

What is @org.eclipse.jnosql.mapping.Convert?

The @org.eclipse.jnosql.mapping.Convert annotation specifies that a field in a Java class should be converted using a custom converter before being stored in the database or retrieved from it. It is particularly useful when you map non-standard or complex data types to and from the database.

How to Use @org.eclipse.jnosql.mapping.Convert

To use the @org.eclipse.jnosql.mapping.Convert annotation, you need to follow these steps:

  1. Annotate Your Field: Place the @Convert annotation above the field you want to convert. In your example, it's used to convert a Currency field.

    @Column
    @Convert(MoneyConverter.class)
    private Currency currency;

    Here, the currency field will be converted using the MoneyConverter class.

  2. Implement the Converter: You'll also need to create a custom converter class that implements the AttributeConverter interface. This interface defines two methods: convertToDatabaseColumn and convertToEntityAttribute.

    public class MoneyConverter implements AttributeConverter<Currency, String> {
    
       @Override
       public String convertToDatabaseColumn(Currency attribute) {
           return attribute.getCurrencyCode();
       }
    
       @Override
       public Currency convertToEntityAttribute(String dbData) {
           return Currency.getAvailableCurrencies().stream()
                   .filter(c -> dbData.equals(c.getCurrencyCode()))
                   .findAny().orElse(null);
       }
    }

    In your MoneyConverter class, you've provided implementations for these methods. The convertToDatabaseColumn method is responsible for converting the Java object to a format that can be stored in the database, and convertToEntityAttribute does the reverse – it converts data retrieved from the database into a Java object.

Using this approach gives you fine-grained control over how data is stored and retrieved from the database, allowing you to handle custom data types flexibly.

Ref: https://github.com/eclipse/jnosql/blob/main/MAPPING.adoc

m4ttek commented 12 months ago

Ok, I get it, but still it doesn't allow me to specify how serde should work for whole entity (like standard Java Externalizable interface).

So, maybe, we should look into it from the other side and give access to creating custom ArangoDB instance with custom serialization objects if needed?

otaviojava commented 12 months ago

Ok, I get it, but still it doesn't allow me to specify how serde should work for whole entity (like standard Java Externalizable interface).

So, maybe, we should look into it from the other side and give access to creating custom ArangoDB instance with custom serialization objects if needed?

Yes, it makes sense to use the driver directly in that case.

otaviojava commented 9 months ago

As we discussed, this one will close as non-fixed.

We have this method that might be helpful:

https://github.com/eclipse/jnosql-databases/blob/main/jnosql-arangodb/src/main/java/org/eclipse/jnosql/databases/arangodb/mapping/ArangoDBTemplate.java#L63