Help: PostgreSQL ByteA (VarBinary, BLOB) & JPA (Hibernate, TopLink, OpenJPA) problem

252 views
Skip to first unread message

Miroslav Nachev

unread,
Feb 5, 2008, 1:21:16 PM2/5/08
to Bulgarian Java Users Group
Здравейте,

Открих проблем който за момента не се сещам как да отсраня. Ако някой се
е сблъсквал с този проблем и има решение би ли ми помогнал?
Проблема е свързан с PostgreSQL и е специфичен за тази база данни. Ако
работя с чист JDBC знам как да го оправя, но проблема е как да го оправя
като използвам JPA Hibernate или друга JPA имплементация. Когато в
дадена таблица има колона от тип ByteA (този тип представлява Binary,
VarBinary и BLOB) получава тази грешка:

2008-2-5 20:10:44 org.hibernate.util.JDBCExceptionReporter logExceptions
SEVERE: ERROR: column "medium_image" is of type bytea but expression is
of type oid

Дори никакви данни да не се подават (NULL), грешката пак се получава.

Имате ли някакви предложения?


Поздрави,
Миро.

Svetlin Nakov

unread,
Feb 5, 2008, 1:28:12 PM2/5/08
to bg-...@googlegroups.com
юГ КХВМН ЯЗЛ ЛЮОБЮК BLOB ЙНКНМХ Б Hibernate ОН 2 МЮВХМЮ:
1) ЙЮРН byte[] - РСЙ МЪЛЮ МХЙЮЙБХ ОПНАКЕЛХ - БЯХВЙН АЮВЙЮ. яЮЛН ДЕРН Е
ОПНАКЕЛМН ДЮ ЯЕ АНПЮБХ ОПХ ЦНКЕЛХ ТЮИКНБЕ (ОПХЛЕПМН БХДЕНЙКХОНБЕ)
2) ЙЮРН ОНРНЙ - РСЙ ЙНДЗР Е ОН-ЯКНФЕМ, МН ОЮЙ ЯРЮБЮ КЕЯМН:
Blob blob = Hibernate.createBlob(stream);
MyEntity.setFile(blob)

мЮЙНБ

-----Original Message-----
From: bg-...@googlegroups.com [mailto:bg-...@googlegroups.com] On Behalf Of
Miroslav Nachev
Sent: Tuesday, February 05, 2008 8:21 PM
To: Bulgarian Java Users Group
Subject: Help: PostgreSQL ByteA (VarBinary, BLOB) & JPA (Hibernate, TopLink,
OpenJPA) problem

гДПЮБЕИРЕ,

нРЙПХУ ОПНАКЕЛ ЙНИРН ГЮ ЛНЛЕМРЮ МЕ ЯЕ ЯЕЫЮЛ ЙЮЙ ДЮ НРЯПЮМЪ. юЙН МЪЙНИ ЯЕ
Е ЯАКЗЯЙБЮК Я РНГХ ОПНАКЕЛ Х ХЛЮ ПЕЬЕМХЕ АХ КХ ЛХ ОНЛНЦМЮК?
оПНАКЕЛЮ Е ЯБЗПГЮМ Я PostgreSQL Х Е ЯОЕЖХТХВЕМ ГЮ РЮГХ АЮГЮ ДЮММХ. юЙН
ПЮАНРЪ Я ВХЯР JDBC ГМЮЛ ЙЮЙ ДЮ ЦН НОПЮБЪ, МН ОПНАКЕЛЮ Е ЙЮЙ ДЮ ЦН НОПЮБЪ
ЙЮРН ХГОНКГБЮЛ JPA Hibernate ХКХ ДПСЦЮ JPA ХЛОКЕЛЕМРЮЖХЪ. йНЦЮРН Б
ДЮДЕМЮ РЮАКХЖЮ ХЛЮ ЙНКНМЮ НР РХО ByteA (РНГХ РХО ОПЕДЯРЮБКЪБЮ Binary,
VarBinary Х BLOB) ОНКСВЮБЮ РЮГХ ЦПЕЬЙЮ:

2008-2-5 20:10:44 org.hibernate.util.JDBCExceptionReporter logExceptions
SEVERE: ERROR: column "medium_image" is of type bytea but expression is
of type oid

дНПХ МХЙЮЙБХ ДЮММХ ДЮ МЕ ЯЕ ОНДЮБЮР (NULL), ЦПЕЬЙЮРЮ ОЮЙ ЯЕ ОНКСВЮБЮ.

хЛЮРЕ КХ МЪЙЮЙБХ ОПЕДКНФЕМХЪ?


оНГДПЮБХ,
лХПН.


Miroslav Nachev

unread,
Feb 5, 2008, 1:33:58 PM2/5/08
to bg-...@googlegroups.com
Това е добре, но в случая аз не вкарвам никакви данни. Полето е празно и
Hibernate се опитва да го зареди със стойност NULL. Не знам дали изобщо
може да се контролира в Hibernate построяването на SQL Statement-а и да
се оказва кои методи да се използват. Особено през Hibernate JPA.


Миро.


Svetlin Nakov wrote:
> Аз лично съм мапвал BLOB колони в Hibernate по 2 начина:
> 1) като byte[] - тук няма никакви проблеми - всичко бачка. Само дето е
> проблемно да се борави при големи файлове (примерно видеоклипове)
> 2) като поток - тук кодът е по-сложен, но пак става лесно:


> Blob blob = Hibernate.createBlob(stream);
> MyEntity.setFile(blob)
>

> Наков


>
> -----Original Message-----
> From: bg-...@googlegroups.com [mailto:bg-...@googlegroups.com] On Behalf Of
> Miroslav Nachev
> Sent: Tuesday, February 05, 2008 8:21 PM
> To: Bulgarian Java Users Group
> Subject: Help: PostgreSQL ByteA (VarBinary, BLOB) & JPA (Hibernate, TopLink,
> OpenJPA) problem
>

> Здравейте,
>
> Открих проблем който за момента не се сещам как да отсраня. Ако някой се
> е сблъсквал с този проблем и има решение би ли ми помогнал?
> Проблема е свързан с PostgreSQL и е специфичен за тази база данни. Ако
> работя с чист JDBC знам как да го оправя, но проблема е как да го оправя
> като използвам JPA Hibernate или друга JPA имплементация. Когато в
> дадена таблица има колона от тип ByteA (този тип представлява Binary,
> VarBinary и BLOB) получава тази грешка:
>

> 2008-2-5 20:10:44 org.hibernate.util.JDBCExceptionReporter logExceptions
> SEVERE: ERROR: column "medium_image" is of type bytea but expression is
> of type oid
>

Svetlin Nakov

unread,
Feb 5, 2008, 2:03:42 PM2/5/08
to bg-...@googlegroups.com
Ами ако си направиш CustomType, можеш да мапваш колоните както ти е кеф. Не
е нужно да контролираш самата заявка, но можеш да контролираш какво се пъха
в PreparedStatement-а и какво се чете от ResultSet-а. Ето пример:

import java.io.Serializable;
import java.sql.Clob;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import oracle.jdbc.driver.OraclePreparedStatement;
import oracle.jdbc.driver.OracleResultSet;
import oracle.sql.OPAQUE;
import oracle.xdb.XMLType;

import org.hibernate.HibernateException;
import org.hibernate.usertype.UserType;
import org.w3c.dom.Document;

/**
* User type for mapping oracle sys.xmltype colums to a org.w3c.Document
* property.
*/
public class OracleXMLTypeUserType implements UserType, Serializable {

/**
* The default serialVersionUID of the class.
*/
private static final long serialVersionUID = 1L;
private static final Class<?> RETURNED_CLASS = Document.class;
private static final int[] SQL_TYPES = new int[] {
XMLType._SQL_TYPECODE };

/**
* {@inheritDoc}
*/
public Object assemble(Serializable cashed, Object owner)
throws HibernateException {
return deepCopy(cashed);
}

/**
* {@inheritDoc}
*/
public Object deepCopy(Object value) throws HibernateException {
if (value instanceof Document) {
Document result = ((Document) value);
return result;
} else {
return null;
}
}

/**
* {@inheritDoc}
*/
public Serializable disassemble(Object value) throws
HibernateException {
return (Serializable) deepCopy(value);
}

/**
* {@inheritDoc}
*/
public boolean equals(Object arg0, Object arg1) throws
HibernateException {
if (arg0 == arg1) {
/*
* Return true if the two arguments are null. or the
same object.
*/
return true;
}
if (arg0 instanceof Document) {
return XMLUtils.toXML((Document) arg0).equals(
XMLUtils.toXML((Document) arg1));
}
return false;
}

/**
* {@inheritDoc}
*/
public int hashCode(Object value) throws HibernateException {
if (value != null) {
return value.hashCode();
} else {
return 0;
}
}

/**
* {@inheritDoc}
*/
public boolean isMutable() {
return false;
}

/**
* {@inheritDoc}
*/
public Object nullSafeGet(ResultSet rs, String[] names, Object obj)
throws HibernateException, SQLException {

XMLType xmlType = null;
try {
OPAQUE value = null;
if (rs instanceof OracleResultSet) {
OracleResultSet ors = (OracleResultSet) rs;
value = ors.getOPAQUE(names[0]);

if (value == null) {
return null;
}
xmlType = XMLType.createXML(value);
Clob clob = xmlType.getClobVal();
return
XMLUtils.newDocument(clob.getCharacterStream());
} else {
throw new HibernateException(
"Sorry only oracle driver is
supported.");
}

} finally {
if (xmlType != null) {
xmlType.close();
}
}
}

/**
* {@inheritDoc}
*/
public void nullSafeSet(PreparedStatement st, Object value, int
index)
throws HibernateException, SQLException {
XMLType xmlType = null;
try {
if (value == null) {
st.setNull(index, XMLType._SQL_TYPECODE,
XMLType._SQL_NAME);
} else {
if (st instanceof OraclePreparedStatement) {
xmlType =
XMLType.createXML(st.getConnection(), XMLUtils
.toXML((Document)
value));
st.setObject(index, xmlType);
} else {
throw new HibernateException(
"Sorry only oracle
driver is supported.");
}
}
} finally {
if (xmlType != null) {
xmlType.close();
}
}
}

/**
* {@inheritDoc}
*/
public Object replace(Object original, Object target, Object owner)
throws HibernateException {
return original;
}

/**
* {@inheritDoc}
*/
public Class<?> returnedClass() {
return RETURNED_CLASS;
}

/**
* {@inheritDoc}
*/
public int[] sqlTypes() {
return SQL_TYPES;
}

}

Svetlin Nakov
Director Training and Consulting Activities
National Academy for Software Development
http://academy.devbg.org

Reply all
Reply to author
Forward
0 new messages