Как настроить ORMLite для сохранения `byte []` как DataType.BYTE_ARRAY?

В моих объектах db у меня есть byte[] поля:

import javax.persistence.*;

/**
 *  Account
 */
@Entity
@Table(name = TABLE)
public class Account {
    public static final String TABLE = "Account";
    ...

    public final static String COLUMN_PASSWORD_HASH = "passwordHash";
    @Column(name = COLUMN_PASSWORD_HASH, nullable = false)
    public byte[] passwordHash;

    ...

Я хочу, чтобы мои объекты db не зависели от какой-либо зависимости от поставщика, поэтому я использую только аннотации JPA и стараюсь избегать любых аннотаций ORMLite или Hibernate.

Однако при попытке сохранить такой объект с помощью ORMLite я получаю следующую ошибку:

java.sql.SQLException: ORMLite не знает, как сохранить класс [B для поля 'passwordHash'. поля byte [] должны указывать dataType = DataType.BYTE_ARRAY или SERIALIZABLE.

Насколько я понимаю, по какой-то причине ORMLite не предпочитает BYTE_ARRAY для byte[] и требует отмечать поля аннотацией com.j256.ormlite.field.Datatype ORMLite, вводя явную зависимость от модуля ormlite-core, и это то, чего я хочу избежать (у меня есть Hibernate DAO impl и ORMLite DAO impl и я не хочу все смешивать).

Моим первоначальным намерением было настроить ORMLite так, чтобы он предпочитал BYTE_ARRAY для byte[] полей. Как я могу это сделать? Стоит ли вводить кастомный персистер? Есть другие предложения?


person 4ntoine    schedule 16.06.2018    source источник
comment
К вашему сведению: ORMLite изначально рассматривал byte[] как Serializable, и я не хотел, чтобы он произвольно менял типы, поэтому я заставил пользователей выбирать тот или другой.   -  person Gray    schedule 19.06.2018


Ответы (1)


Я решил это, добавив следующие настраиваемые данные для сохранения (без добавления зависимости от ormlite-core, как я хотел):

package name.antonsmirnov.zzz.dao.types;

import com.j256.ormlite.field.SqlType;
import com.j256.ormlite.field.types.ByteArrayType;

/**
 * ByteArray Type that prefers storing byte[] as BYTE_ARRAY
 */
public class PreferByteArrayType extends ByteArrayType {

    public PreferByteArrayType() {
        super(SqlType.BYTE_ARRAY, new Class[] { byte[].class });
    }

    private static final PreferByteArrayType singleTon = new PreferByteArrayType();

    public static PreferByteArrayType getSingleton() {
        return singleTon;
    }
}

Зарегистрируйте его так же, как и любой другой пользовательский персистер:

DataPersisterManager.registerDataPersisters(PreferByteArrayType.getSingleton());

Обратите внимание, что вы не можете использовать значение по умолчанию ByteArrayDataType, потому что он имеет пустой массив classes, поэтому он становится постоянным для автоматически сгенерированных полей и вызывает исключение, что поля байтового массива не могут быть полями идентификатора.

Я проверил, что для MySQL используется тип BLOB полей:

com.mysql.jdbc.Field@39a2bb97 [каталог = test_db, tableName = account, originalTableName = account, columnName = passwordHash, originalColumnName = passwordHash, mysqlType = 252 (FIELD_TYPE_BLOB), flags = BINARY BLOB, charset-Index = 63 8859-1]

person 4ntoine    schedule 16.06.2018