Получение почти удвоенной длины при чтении байта [] из postgres с помощью jpa
У меня есть класс Image, который имеет байт [] для хранения фактических данных изображения. Я могу загрузить и вставить изображение просто отлично в моем веб-приложении. Когда я пытаюсь отобразить изображение после чтения его из JPA, длина моего байта [] всегда равна 2x-1 или 2x-2, где x - длина поля bytea в postgres 9. Очевидно, что браузер не будет отображаться изображение говорит, что оно повреждено. Я мог бы использовать некоторую помощь, чтобы выяснить, почему я получаю (примерно) вдвое больше, чем я ожидаю. Вот отображение моего класса изображения. Используя eclipselink с JPA 2, нажмите Postgres 9 на Mac.
Когда я выбираю из базы данных с
select *, length(bytes) from image;
Я получаю длину 9765. В точке останова моего контроллера длина байта [] равна 19529, что на один байт вдвое больше, чем в базе данных.
@Entity
@Table( name = "image" )
@SequenceGenerator( name = "IMAGE_SEQ_GEN", sequenceName = "IMAGE_SEQUENCE" )
public class Image
extends DataObjectAbstract<Long>
{
@Id
@GeneratedValue( strategy = GenerationType.SEQUENCE, generator = "IMAGE_SEQ_GEN" )
private Long key;
@Column( name="content_type" )
private String contentType;
@Lob
@Basic( optional=false )
@Column( name="bytes" )
private byte[] bytes;
// constructor and getters and setters
}
pgadmin показывает мне следующее для таблицы изображений
CREATE TABLE image
(
"key" bigint NOT NULL,
bytes bytea,
content_type character varying(255),
"version" integer,
CONSTRAINT image_pkey PRIMARY KEY (key)
)
WITH (
OIDS=FALSE
);
5 ответов
В PostgreSQL 9 byte[] отправляется клиенту с использованием шестнадцатеричной кодировки.
Если это является причиной ошибки, вы должны найти обновление для JPA. Или вы можете изменить конфигурацию сервера БД, но предыдущий лучше.
"Bytea_output = escape" - это просто обходной путь, Postgres 8.0 изменил кодировку bytea на hex.
Используйте текущий драйвер JDBC начиная с 9.0-dev800 (9.0 Build 801 обновлен в настоящее время), и проблема будет решена.
Дополнительный ответ для пользователей GlassFish 3.x (принципы могут применяться к другим серверам приложений)
Вы можете случайно использовать старый драйвер PostgreSQL JDBC. Вы можете проверить это, введя DataSource
где-то (например, EJB) и выполняем на нем следующее:
System.out.println(ds.getConnection().getMetaData().getDriverVersion());
В моем случае это был 8.3, что было неожиданно, поскольку я развертывал с драйверами 9.1.
Чтобы выяснить, откуда это происходит:
System.out.println(Class.forName("org.postgresql.Driver").getProtectionDomain().getCodeSource().getLocation());
Как оказалось для меня, это было в каталоге lib моего домена GlassFish. Я не уверен, как он туда попал - GlassFish, конечно, не доставляет таким образом - поэтому я просто удалил его, и проблема ушла.
Проверьте, есть ли у вас старая банка postgresql. Я столкнулся с той же проблемой и обнаружил в своей библиотеке и jar-файл 8.3 postgresql, и jar-файл 9.1 postgresql. После удаления 8.3 postgresql, byte[] работает нормально.
Попробуйте посмотреть на данные, которые вы получаете. Это может дать вам ключ к пониманию того, что происходит.