36

I wanna store an entity(a String + an image) in PostgresQL using Spring MVC and Hibernate Here is my table. The image is supposed to be the type of oid.

CREATE TABLE document
(
  name character varying(200),
  id serial NOT NULL,
  content oid,   // that should be the image
  CONSTRAINT document_pkey PRIMARY KEY (id )
)
WITH (
  OIDS=FALSE
);

Here is the entity that I want to store.

    @Entity
    @Table(name = "document")
    public class Document {

        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        @Column(name = "id")
        private Long id;

        @Column(name = "name")
        private String name;

        @Column(name="content")
            private Blob content;  //this is the image
//getters- setters

You can see the variable "name" is a String, not Long. Still when I submit the form with a value which is not numeric it throws org.postgresql.util.PSQLException: Bad value for type long : x

here is the form:

<form:form method="post" action="save.html" commandName="document" enctype="multipart/form-data">
    <form:errors path="*" cssClass="error"/>
    <table>
    <tr>
        <td><form:label path="name">Name</form:label></td>
        <td><form:input path="name" /></td> 
    </tr>

     <tr>
        <td><form:label path="content">Document</form:label></td>
        <td><input type="file" name="file" id="file"></input></td>
    </tr>
    <tr>
        <td colspan="2">
            <input type="submit" value="Add Document"/>
        </td>
    </tr>
</table>  
</form:form>

If I enter a numeric value and submit it, OK. But any non-numeric value triggers the above mentioned exception...I read that it might be caused by that I do not use OID properly but I do not know what should I do to eliminate this exception. Actually I do not understand the name of the excpetion either. It says "bad value for type long" . but who wants type long? the variable "name" is type String!!!!

Finally, here is the Controller

@RequestMapping(value = "/save", method = RequestMethod.POST)
public String save(@ModelAttribute("document") Document document, @RequestParam("file") MultipartFile file) {

    try {
        Blob blob = Hibernate.createBlob(file.getInputStream());
        document.setContent(blob);
        documentDao.save(document);
    } catch (Exception e) {
        e.printStackTrace();
    }


    return "redirect:/index.html";
}

Any advice is appriciated.

athspk
  • 6,722
  • 7
  • 37
  • 51
Sanyifejű
  • 2,610
  • 10
  • 46
  • 73
  • 1
    You may want to try annotating your Blob declaration with the hibernate @Lob annotation. Also, it may help to turn on hibernate's query output so you can see the sql that is being generated and see if it gives you a hint as to what is being sent to the database. – jcern Sep 28 '12 at 22:01
  • An OID can't hold a BLOB. ["The oid type is currently implemented as an unsigned four-byte integer."](http://www.postgresql.org/docs/9.0/static/datatype-oid.html). I suppose that's where the error comes from. – madth3 Sep 28 '12 at 22:33
  • @madth3 `oid` is used to hold a reference to a large object in the `pg_largeobject` table. – Craig Ringer Sep 28 '12 at 23:40
  • Of course, sorry for that. Did you check [this question](http://stackoverflow.com/q/1333596/422353)? What version of PostgreSQL are you using? – madth3 Sep 28 '12 at 23:46
  • What version of PostgreSQL are you using? PostgreSQL 9.1 – Sanyifejű Sep 29 '12 at 19:22

6 Answers6

96

I had a similiar problem but it was not related to the order of ID field in the database.

After some searching I found this pointing to the fact that Lobs in Hibernate are treated as OIDs unless otherwise specified.

That means Hibernate will try put a Lob into a Long a hence produce that exception PSQLException: Bad value for type long

The way to specify that the Lob is a to be treated as text is by annotating the field

@Lob
@Type(type = "org.hibernate.type.TextType")
Tšeliso Molukanele
  • 1,630
  • 12
  • 18
10

when I created the table the column "name" happened to be the first. That's not good. Id must be the first column. If I change the order of columns it works fine...

Sanyifejű
  • 2,610
  • 10
  • 46
  • 73
6

At first I tried to set

@Column(columnDefinition = "text")

instead of @Lob annotation, as already mentioned here. It worked for me on PostgreSQL, but with error org.hibernate.tool.schema.spi.SchemaManagementException: Schema-validation: wrong column type encountered in column [htmlText] in table [Question]; found [clob (Types#CLOB)], but expecting [text (Types#VARCHAR)]

in my unit tests (on HSQLDB).

Then it tried

@Column(columnDefinition = "clob")

And it works well on both PostgreSQL and HSQLDB!

GreenTea
  • 344
  • 3
  • 9
2

Problem exist on Postgres and Hibernate. Column text can't be mapped to String. You need to add : @Type(type="org.hibernate.type.TextType")

Example :

@Lob
@Type(type = "org.hibernate.type.TextType")
@Column
private String contentJson;

If column contains binary type, use : @Type(type="org.hibernate.type.BinaryType")

Solution founded on page : https://github.com/jhipster/generator-jhipster/issues/5995

Tomasz
  • 884
  • 8
  • 12
1

Use the @Column and columnDefinition to stay compliant with the JPA spec

@Column(columnDefinition = "CLOB")

or Hibernate annotation @Type with JPA @Lob annotation if its okay for you to use Hibernate annotations

@Lob
@Type(type = "org.hibernate.type.TextType")
-1

I faced smiler error and the reason was that I was having some characters other than integer in integer data type filed

e.g.- ,111 and 144- etc

Shubham
  • 434
  • 6
  • 12