Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

byte[] mapping problem #62

Open
ArtDu opened this issue Oct 21, 2021 · 2 comments
Open

byte[] mapping problem #62

ArtDu opened this issue Oct 21, 2021 · 2 comments
Labels

Comments

@ArtDu
Copy link
Contributor

ArtDu commented Oct 21, 2021

Добрый день. Средствами cartridge-springdata можно как-то сложить данные в бинарном виде? Пробовал менять поле на varbinary, говорит, что не может строку преобразовать в varbinary, хотя в сущности поле определено с типом byte[]. Пробовал в тарантуле поле оставлять строковым, а в сущности byte[], тоже не работает. В тестах репозитория не нашел примеров с вставкой бинарных данных в тарантул средствами java

To reproduce the problem, I took an existing test by adding a byte [] field to the entity

@Test
public void testSave() {
    BookTranslation translation = BookTranslation.builder()
            .bookId(2)
            .language("Russian")
            .edition(22)
            .translator("Ivan Ivanov")
            .comments("Some translation")
            .bytesString("Hello".getBytes())
            .build();
    BookTranslation newTranslation = bookTranslationRepository.save(translation);
    assertThat(newTranslation).isEqualTo(translation);
}
diff --git a/src/test/java/org/springframework/data/tarantool/entities/BookTranslation.java b/src/test/java/org/springframework/data/tarantool/entities/BookTranslation.java
index 7ea062d..6e573a7 100644
--- a/src/test/java/org/springframework/data/tarantool/entities/BookTranslation.java
+++ b/src/test/java/org/springframework/data/tarantool/entities/BookTranslation.java
@@ -33,4 +33,6 @@ public class BookTranslation {
     private String translator;

     private String comments;
+
+    private byte[] bytesString;
 }
diff --git a/src/test/java/org/springframework/data/tarantool/repository/support/CompositePkIntegrationTest.java b/src/test/java/org/springframework/data/tarantool/repository/support/CompositePkIntegrationTest.java
index 1b42bd1..b7c69ea 100644
--- a/src/test/java/org/springframework/data/tarantool/repository/support/CompositePkIntegrationTest.java
+++ b/src/test/java/org/springframework/data/tarantool/repository/support/CompositePkIntegrationTest.java
@@ -62,6 +62,7 @@ class CompositePkIntegrationTest extends BaseIntegrationTest {
                 .edition(22)
                 .translator("Ivan Ivanov")
                 .comments("Some translation")
+                .bytesString("Hello".getBytes())
                 .build();
         BookTranslation newTranslation = bookTranslationRepository.save(translation);
         assertThat(newTranslation).isEqualTo(translation);
diff --git a/src/test/resources/cartridge/app/roles/api_storage.lua b/src/test/resources/cartridge/app/roles/api_storage.lua
index cdc7fa6..3f1ad7f 100644
--- a/src/test/resources/cartridge/app/roles/api_storage.lua
+++ b/src/test/resources/cartridge/app/roles/api_storage.lua
@@ -86,6 +86,7 @@ local function init_space()
                     { name = 'edition', type = 'integer' },
                     { name = 'translator', type = 'string' },
                     { name = 'comments', type = 'string', is_nullable = true },
+                    { name = 'bytesString', type = 'string', is_nullable = true }
                 },
                 if_not_exists = true,
             }

Reproducer showed that data is written to tarantool normally, since messagePack binary is processed as a string in a tarantool. But we cannot get them back to java, since messagePack String comes and we are trying to convert it tobyte []

The problem is that byte [] is collection, and the code asks us to return list

if (propType.isCollectionLike()) {
value = ((TarantoolTuple) source).getList(fieldName);

The workaround was to use a custom mapper:

MessagePackMapper defaultMapper =
                DefaultMessagePackMapperFactory.getInstance().defaultComplexTypesMapper();
        defaultMapper.registerValueConverter(
                ImmutableStringValueImpl.class, List.class, object -> {
                    final List<Byte> list = new ArrayList<>();
                    for (byte b : object.toString().getBytes()) {
                        list.add(b);
                    }
                    return list;
                });

Also globally the problem may be related to this: tarantool/tarantool#1629

@akudiyar
Copy link
Collaborator

This bug must be fixed in the driver, I opened an issue tarantool/cartridge-java#144.

Storing byte arrays in the fields of type string requires a custom string-to-byte-array conversion on the client level using SpringData's custom converters mechanism (see

). It is a valid w/a for this case, although creating Strings and then converting them into byte arrays may result in a huge memory overhead on the client.

@dkasimovskiy
Copy link
Contributor

Could be implrmrnted only for Tarantool 3.0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants