3

I have an Image class that has a byte[] to contain the actual image data. I'm able to upload and insert the image just fine in my webapp. When I attempt to display the image after reading it from JPA the length of my byte[] is always either 2x-1 or 2x-2, where x is the length of the bytea field in postgres 9. Obviously the browser won't display the image saying it's corrupted. I could use some help figuring out why I'm getting (about) twice what I expect. Here's the mapping of my image class. Using eclipselink with JPA 2 hitting postgres 9 on a mac.

When I select from the database with

select *, length(bytes) from image;

I get a length of 9765. In a breakpoint in my controller the byte[] length is 19529 which is one byte shy of twice what's in the database.

@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 shows me the following for the image table

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
);
digitaljoel
  • 26,265
  • 15
  • 89
  • 115

5 Answers5

4

The "bytea_output = escape" is just a workaround, Postgres 8.0 changed the bytea encoding to hex.

Use a current JDBC driver since 9.0-dev800 (9.0 Build 801 is up-to-date currently) and the problem will be solved.

samy-delux
  • 3,061
  • 2
  • 29
  • 32
  • This suggestion and others are just wild stabs in the dark. In my case, 9.0 server with 9.0 JDBC drivers worked. 9.1 server with 9.1 JDBC drivers has this problem. – Steve Jan 15 '12 at 00:44
3

In PostgreSQL 9 byte[] is sent to client using hex encoding.

If this is reason for error you have to find update for JPA. Or you may change config of DB server but previous is better.

jordani
  • 436
  • 3
  • 3
  • interesting that I haven't done any configuration and it works if I'm running the server in windows, but not mac. Any thoughts on that? – digitaljoel May 31 '11 at 00:02
  • It may be as simple as making sure that: bytea_output = escape is present in postgresql.conf I have read this soon and I hope it can help you. Is Postgre in windows v. 9 or earlier? – jordani May 31 '11 at 00:14
  • I didn't look much at the configuration on the windows box, but came back to my mac and set the property and things are looking good. I appreciate the help?! – digitaljoel May 31 '11 at 01:44
  • Like what @jordani suggested, the JDBC driver is treating the `BYTEA[]` as `TEXT` even though the data type is `BYTEA[]` on the server. Proper decoding the hex values in to a binary value should solve the problem (an all too common problem with some drivers). – Sean May 31 '11 at 20:52
2

Supplementary answer for GlassFish 3.x users (principles may apply to other app servers)

You may be inadvertently using an old PostgreSQL JDBC driver. You can test this by injecting a DataSource somewhere (e.g. an EJB) and executing the following on it:

System.out.println(ds.getConnection().getMetaData().getDriverVersion());

In my case, it was 8.3 which was unexpected since I was deploying with 9.1 drivers.

To find out where this was coming from:

System.out.println(Class.forName("org.postgresql.Driver").getProtectionDomain().getCodeSource().getLocation());

As it turned out for me, it was in the lib directory of my GlassFish domain. I'm not sure how it got there - GlassFish certainly doesn't ship that way - so I just removed it and the problem went away.

Steve
  • 8,066
  • 11
  • 70
  • 112
0

Check whether you have an old postgresql jar. I faced the same problem, and found both 8.3 postgresql jar and a 9.1 postgresql jar in my lib. After remove 8.3 postgresql, byte[] works fine.

Jiong
  • 1
0

Try looking at the data you're getting. It may give you a clue as to what's happening.

MRAB
  • 20,356
  • 6
  • 40
  • 33