2011-11-21 23 views
9

Jeśli entity.getHistory() jest zerowy kod następujący fragment:PostgreSQL JDBC Null String traktowane jako bytea

(getEntityManager() zwraca wiosna wstrzykuje EntityManager, baza danych typu historia pole jest: tekst lub varchar2 (2000)

Query query = getEntityManager().createNativeQuery("insert into table_name(..., history, ....) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)") 
[...] 
.setParameter(6, entity.getHistory()) 
[...] 

query.executeUpdate(); 

daje dziwny wyjątek:

17/11/11 06:26:09:009 [pool-2-thread-1] WARN util.JDBCExceptionReporter:100 - SQL Error: 0, SQLState: 42804 
17/11/11 06:26:09:009 [pool-2-thread-1] ERROR util.JDBCExceptionReporter:101 - ERROR: **column "history" is of type text but expression is of type bytea** 

Podpowiedź: trzeba będzie przerobić lub rzucać ekspresję

.

problem wystąpił tylko w tej konfiguracji:
OS: CentOS zwolnić 5,6 (Final)
Java: 1.6.0_26
DB: PostgreSQL 8.1
JDBC Kierowca: postgresql-9.1-901.jdbc4
Application Server: Apache -tomcat-6.0.28

Wszystko działa dobrze w kilku innych konfiguracjach lub gdy historia jest pustym ciągiem znaków. To samo wyrażenie wykonane z pgAdmin działa poprawnie.

Zgaduję, że problem występuje w sterowniku JDBC PostgreSQL, czy istnieje jakiś rozsądny powód, aby traktować pusty łańcuch jako wartość bajtu? Może jakieś dziwne zmiany między Postgresem 8 a 9?

+0

Podejrzewam, że EntityManager wywołuje niewłaściwą metodę "PreparedStatement.setXXX()" dla wartości NULL. Możesz także wypróbować sterownik 8.1 JDBC. Btw: czy wiesz, że 8.1 nie jest już obsługiwany? –

+0

Czy możesz wyjaśnić swoje pierwsze dwa akapity? Nie wydają się mieć sensu. –

+0

Ten sam kod działa poprawnie z PostgreSQL 9+ (@a_horse_with_no_name Klient musi mieć 8.1 ...), Windows 7 itd. Jeśli entity.getHistory() ma "" wartość zamiast null, to działa. Ta sama wstawka wykonana z pgAdmin działa poprawnie. – laidlook

Odpowiedz

1

Jeśli jesteś gotów użyć klasy zamiast Query PreparedStatement:

if (entity.getHistory() == null) 
    stmt.setNull(6, Types.VARCHAR); 
else 
    stmt.setString(6, entity.getHistory()); 

(Możliwe jest, że za pomocą ?::text w ciągu kwerendy będzie również działać, ale nigdy nie robiłem to w ten sposób siebie.)

4

Ponieważ wywołujesz setParameter(int,Object) z wartością pustą, przy odgadywaniu menedżer encji nie ma pojęcia, który typ trwałości należy użyć do powiązania parametru. Istr Hibernate ma predylekcję do korzystania z SerializableType, co oznaczałoby bytea.

Czy można użyć metody setParameter, która pobiera obiekt parametru, aby można było określić typ? Tak naprawdę nie używałem JPA, więc nie mogę podać szczegółowego wskaźnika.

(IMHO to jest twój tylko desery za nadużywanie interfejs zapytań native sql EntityManager, aby zrobić wkładki, zamiast faktycznie mapowania podmiotu, lub po prostu spada poprzez JDBC)

4

Jest prosty dylemat: jeśli jesteś budując ciąg kwerendy, jeśli parametr ma być pusty - użyj "null" zamiast "?".

Jak mówi @araqnid, Hibernacja nieprawidłowo rzuca wartości null do bajtu typu, ponieważ nie wie nic lepszego.

0

Parametr JDBC setNull z parametrem sql jest powrotem do starszych sterowników JDBC, które nie przekazują pakietu JDBC Driver Test Suite.

Można ustrzec się przed błędami zerowych w zapytaniu następująco:

wybrać od autora a gdzie: lastName IS NULL lub niższy (a.lastName) =: lastName

To powinno działać w PostgreSQL po poprawka tego issue.

0

Korzystanie Hibernate określonej sesji API działa jako obejście:

String sql = "INSERT INTO person (id, name) VALUES (:id, :name)"; 
Session session = em.unwrap(Session.class); 
SQLQuery insert = session.createSQLQuery(sql); 
sql.setInteger("id", 123); 
sql.setString("name", null); 
insert.executeUpdate(); 

Ja również złożony HHH-9165 zgłosić ten problem, jeśli to rzeczywiście błąd.

+0

note Miałem ten problem z 'Short' i tam nie można użyć' setShort() ', ponieważ zajmuje' '' '' '' '' '' '' 'short'. W hibernacji 4.x rozwiązaniem jest: '.setParameter (" short ", ShortValue, ShortType.INSTANCE);' (z 3.x myślę, że to 'Hibernate.SHORT' zamiast używać' ShortType'). –

Powiązane problemy