8
CREATE TABLE customers
(
  first_name character varying(15),
  second_name character varying(20),
  login character varying(15) NOT NULL,
  password character varying(15),
  email character varying(40),
  gender gender,
  register_date date,
  date_of_birth date,
  address character varying(40),
  address_number integer,
  town character varying(20),
  CONSTRAINT login PRIMARY KEY (login)
)

I have this table and I created an enum of gender such as:

CREATE TYPE gender AS ENUM ( 'F', 'M',);

I am trying to insert into customers data from eclipse java with PreparedStatement but there is an error such as ERROR: column "gender" is of type gender but expression is of type character varying Hint: You will need to rewrite or cast the expression.

My Java code looks like:

PreparedStatement pre_state;

public enum gendertype {
    F,
    M;
}

pre_state = conn.prepareStatement("INSERT INTO"
            + " customers VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
pre_state.set(6, gendertype.F.toString());
Willi Mentzel
  • 27,862
  • 20
  • 113
  • 121
user2317288
  • 99
  • 1
  • 2
  • 3
  • It's probably inserting it as `'F'::text`, which would cause the error. – Mike Christensen May 10 '13 at 23:59
  • ok i found as solution and it works – user2317288 May 11 '13 at 00:13
  • pre_state=main.conne.conn.prepareStatement("insert into customers values (?,?,?,?,?,?::gender,?,?,?,?,?)"); – user2317288 May 11 '13 at 00:14
  • pre_state.setString(6,gendertype.F.toString()); – user2317288 May 11 '13 at 00:15
  • 8
    Please consider adding an `Other` and/or `unspecified` value for `gender`. Gender isn't simply two values; you have genetically XXY individuals, developmentally intersex individuals, etc. Like assuming that names has a "first name" and "surname" it's a bad habit in computing that needs to go away. – Craig Ringer May 11 '13 at 00:40
  • @CraigRinger that's an excellent point. I know someone who has only one name, which is "LynC". Her drivers licence has a dot as her first name... etc. Don't be too prescriptive with data – Bohemian May 11 '13 at 02:38

3 Answers3

15

I can take no credit for this answer as you have already solved it, but I will explain why it works.

PostgreSQL provides the answer when it says

Hint: You will need to rewrite or cast the expression

The Java code is creating a string literal value that represents the Java enum gendertype type.

Casting a literal to a PostgreSQL gender type is done by adding a casting suffix to the value ::gender.

So valid input would be

'F'::gender

or

'M'::gender

This works because all PostgreSQL types have a input method that takes a text representation and converts that to the internal form.

Drew Noakes
  • 300,895
  • 165
  • 679
  • 742
Tim Child
  • 2,994
  • 1
  • 26
  • 25
2

Your solution would have been

pre_state.setObject(6, gendertype.F.toString(), Types.OTHER);
abbas
  • 6,453
  • 2
  • 40
  • 36
0

In addition to other answers if you use for example createNativeQuery() you should cast value to your enum like cast(? as gender), something like that:

Person person = new Person("Gurbanguly", "Berdymukhamedov", Gender.Male)
Session session = HibernateUtil.getSessionFactory().openSession();
Transaction transaction = session.beginTransaction();
session.createNativeQuery("INSERT INTO Person (firstname, lastname, gender) VALUES (?,?,cast(? as gender))")
            .setParameter(1, person.getFirstName())
            .setParameter(2, person.getLastName())
            .setParameter(3, person.getGender().toString())
            .executeUpdate();
transaction.commit();
session.close(); // this statement is needed not to produce many sessions
Dmitriy Fialkovskiy
  • 3,065
  • 8
  • 32
  • 47