Java 枚举和 PostgreSQL 枚举

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)
)

我有一个表格,我创建了一个性别枚举,例如:

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

我将尝试使用PreparedStatement从Eclipse Java中插入客户数据,但是出现了错误,例如“ERROR:column“gender”是gender类型,但表达式是字符变量类型 提示:您需要重写或转换该表达式。”
我的Java代码如下:
PreparedStatement pre_state;

public enum gendertype {
    F,
    M;
}

pre_state = conn.prepareStatement("INSERT INTO"
            + " customers VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
pre_state.set(6, gendertype.F.toString());

它可能会将其插入为'F'::text,这将导致错误。 - Mike Christensen
好的,我找到了解决方案并且它有效。 - user2317288
pre_state=main.conne.conn.prepareStatement("insert into customers values (?,?,?,?,?,?::gender,?,?,?,?,?)"); - user2317288
pre_state.setString(6,gendertype.F.toString()); - user2317288
8
请考虑为“性别”添加“其他”和/或“未指定”的值。性别不仅仅是两个值;还有基因上的XXY个体、发育上的间性个体等。就像假设名字有“名字”和“姓氏”一样,这是计算机中需要消除的坏习惯。 - Craig Ringer
@CraigRinger 非常好的观点。我认识一个只有一个名字的人,叫“LynC”。她的驾照上把点作为她的名字...等等。不要对数据过于严格。 - Bohemian
3个回答

15
我不能为这个答案做出任何贡献,因为你已经解决了它,但我会解释为什么它有效。
PostgreSQL 提供了答案,因为它说:
“提示:您需要重写或转换表达式。”
Java 代码正在创建一个表示 Java 枚举 gendertype 类型的字符串文字值。
将字面量转换为 PostgreSQL 性别类型是通过在值后添加转换后缀 ::gender 来完成的。
因此,有效的输入将是:
'F'::gender
或者
'M'::gender

之所以有效,是因为所有的PostgreSQL类型都有一个输入方法,它接受文本表示并将其转换为内部形式。


2
您的解决方案应该是:
pre_state.setObject(6, gendertype.F.toString(), Types.OTHER);

0
除了其他答案外,如果您使用createNativeQuery(),您应该将值强制转换为您的enum,例如cast(? as gender)之类的东西:
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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接