Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.5k views
in Technique[技术] by (71.8m points)

postgresql - Java Enums, JPA and Postgres enums - How do I make them work together?

We have a postgres DB with postgres enums. We are starting to build JPA into our application. We also have Java enums which mirror the postgres enums. Now the big question is how to get JPA to understand Java enums on one side and postgres enums on the other? The Java side should be fairly easy but I'm not sure how to do the postgres side.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I've actually been using a simpler way than the one with PGObject and Converters. Since in Postgres enums are converted quite naturally to-from text you just need to let it do what it does best. I'll borrow Arjan's example of moods, if he doesn't mind:

The enum type in Postgres:

CREATE TYPE mood AS ENUM ('sad', 'ok', 'happy');

The class and enum in Java:

public @Entity class Person {

  public static enum Mood {sad, ok, happy};

  @Enumerated(EnumType.STRING)
  Mood mood;

}

That @Enumerated tag says that serialization/deserialization of the enum should be done in text. Without it, it uses int, which is more troublesome than anything.

At this point you have two options. You either:

  1. Add stringtype=unspecified to the connection string, as explained in JDBC connection parameters.This lets Postgres guess the right-side type and convert everything adequately, since it receives something like 'enum = unknown', which is an expression it already knows what to do with (feed the ? value to the left-hand type deserialiser). This is the preferred option, as it should work for all simple UDTs such as enums in one go.

    jdbc:postgresql://localhost:5432/dbname?stringtype=unspecified
    

Or:

  1. Create an implicit conversion from varchar to the enum in the database. So in this second case the database receives some assignment or comparison like 'enum = varchar' and it finds a rule in its internal catalog saying that it can pass the right-hand value through the serialization function of varchar followed by the deserialization function of the enum. That's more steps than should be needed; and having too many implicit casts in the catalog can cause arbitrary queries to have ambiguous interpretations, so use it sparingly. The cast creation is:

    CREATE CAST (CHARACTER VARYING as mood) WITH INOUT AS IMPLICIT;

Should work with just that.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...