引起原因:org.postgresql.util.PSQLException:错误:类型“枚举”不存在

时间:2019-07-09 09:59:36

标签: java postgresql spring-boot spring-data-jpa lombok

我正在使用 Spring Data JPA,Spring Boot 2.1.6.RELEASE + Postgres 11.0和Lombok 示例。在此示例中,创建架构时出现以下错误。

我遇到了错误。

Hibernate: 

    drop table if exists test.student cascade
2019-07-09 15:23:17.055  WARN 14860 --- [           main] o.h.engine.jdbc.spi.SqlExceptionHelper   : SQL Warning Code: 0, SQLState: 00000
2019-07-09 15:23:17.056  WARN 14860 --- [           main] o.h.engine.jdbc.spi.SqlExceptionHelper   : table "student" does not exist, skipping
Hibernate: 

    create table test.student (
       student_id  bigserial not null,
        crte_user_id varchar(30) not null,
        crte_ts TIMESTAMP WITHOUT TIME ZONE DEFAULT CURRENT_TIMESTAMP not null,
        lst_updt_ts TIMESTAMP WITHOUT TIME ZONE not null,
        lst_updt_user_id varchar(30),
        status ENUM('A', 'I'),
        student_name varchar(255) not null,
        primary key (student_id)
    )
2019-07-09 15:23:17.065  WARN 14860 --- [           main] o.h.t.s.i.ExceptionHandlerLoggedImpl     : GenerationTarget encountered exception accepting command : Error executing DDL "
    create table test.student (
       student_id  bigserial not null,
        crte_user_id varchar(30) not null,
        crte_ts TIMESTAMP WITHOUT TIME ZONE DEFAULT CURRENT_TIMESTAMP not null,
        lst_updt_ts TIMESTAMP WITHOUT TIME ZONE not null,
        lst_updt_user_id varchar(30),
        status ENUM('A', 'I'),
        student_name varchar(255) not null,
        primary key (student_id)
    )" via JDBC Statement

org.hibernate.tool.schema.spi.CommandAcceptanceException: Error executing DDL "
    create table test.student (
       student_id  bigserial not null,
        crte_user_id varchar(30) not null,
        crte_ts TIMESTAMP WITHOUT TIME ZONE DEFAULT CURRENT_TIMESTAMP not null,
        lst_updt_ts TIMESTAMP WITHOUT TIME ZONE not null,
        lst_updt_user_id varchar(30),
        status ENUM('A', 'I'),
        student_name varchar(255) not null,
        primary key (student_id)
    )" via JDBC Statement
    at org.hibernate.tool.schema.internal.exec.GenerationTargetToDatabase.accept(GenerationTargetToDatabase.java:67) ~[hibernate-core-5.3.10.Final.jar:5.3.10.Final]
    at org.hibernate.tool.schema.internal.SchemaCreatorImpl.applySqlString(SchemaCreatorImpl.java:440) [hibernate-core-5.3.10.Final.jar:5.3.10.Final]
    at org.hibernate.tool.schema.internal.SchemaCreatorImpl.applySqlStrings(SchemaCreatorImpl.java:424) [hibernate-core-5.3.10.Final.jar:5.3.10.Final]
    at org.hibernate.tool.schema.internal.SchemaCreatorImpl.createFromMetadata(SchemaCreatorImpl.java:315) [hibernate-core-5.3.10.Final.jar:5.3.10.Final]
    at org.hibernate.tool.schema.internal.SchemaCreatorImpl.performCreation(SchemaCreatorImpl.java:166) [hibernate-core-5.3.10.Final.jar:5.3.10.Final]
    at org.hibernate.tool.schema.internal.SchemaCreatorImpl.doCreation(SchemaCreatorImpl.java:135) [hibernate-core-5.3.10.Final.jar:5.3.10.Final]
    at org.hibernate.tool.schema.internal.SchemaCreatorImpl.doCreation(SchemaCreatorImpl.java:121) [hibernate-core-5.3.10.Final.jar:5.3.10.Final]
    at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.performDatabaseAction(SchemaManagementToolCoordinator.java:155) [hibernate-core-5.3.10.Final.jar:5.3.10.Final]
    at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.process(SchemaManagementToolCoordinator.java:72) [hibernate-core-5.3.10.Final.jar:5.3.10.Final]
    at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:310) [hibernate-core-5.3.10.Final.jar:5.3.10.Final]
    at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:467) [hibernate-core-5.3.10.Final.jar:5.3.10.Final]
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:939) [hibernate-core-5.3.10.Final.jar:5.3.10.Final]
    at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:57) [spring-orm-5.1.8.RELEASE.jar:5.1.8.RELEASE]
    at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:365) [spring-orm-5.1.8.RELEASE.jar:5.1.8.RELEASE]
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:390) [spring-orm-5.1.8.RELEASE.jar:5.1.8.RELEASE]
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:377) [spring-orm-5.1.8.RELEASE.jar:5.1.8.RELEASE]
    at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:341) [spring-orm-5.1.8.RELEASE.jar:5.1.8.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1837) [spring-beans-5.1.8.RELEASE.jar:5.1.8.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1774) [spring-beans-5.1.8.RELEASE.jar:5.1.8.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:593) [spring-beans-5.1.8.RELEASE.jar:5.1.8.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:515) [spring-beans-5.1.8.RELEASE.jar:5.1.8.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:320) [spring-beans-5.1.8.RELEASE.jar:5.1.8.RELEASE]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) ~[spring-beans-5.1.8.RELEASE.jar:5.1.8.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318) [spring-beans-5.1.8.RELEASE.jar:5.1.8.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) [spring-beans-5.1.8.RELEASE.jar:5.1.8.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1105) ~[spring-context-5.1.8.RELEASE.jar:5.1.8.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:867) ~[spring-context-5.1.8.RELEASE.jar:5.1.8.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:549) ~[spring-context-5.1.8.RELEASE.jar:5.1.8.RELEASE]
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:140) ~[spring-boot-2.1.6.RELEASE.jar:2.1.6.RELEASE]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:742) ~[spring-boot-2.1.6.RELEASE.jar:2.1.6.RELEASE]
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:389) ~[spring-boot-2.1.6.RELEASE.jar:2.1.6.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:311) ~[spring-boot-2.1.6.RELEASE.jar:2.1.6.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1213) ~[spring-boot-2.1.6.RELEASE.jar:2.1.6.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1202) ~[spring-boot-2.1.6.RELEASE.jar:2.1.6.RELEASE]
    at com.example.MyProgramApplication.main(MyProgramApplication.java:17) ~[classes/:na]
Caused by: org.postgresql.util.PSQLException: ERROR: type "enum" does not exist
  Position: 314
    at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2440) ~[postgresql-42.2.5.jar:42.2.5]
    at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2183) ~[postgresql-42.2.5.jar:42.2.5]
    at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:308) ~[postgresql-42.2.5.jar:42.2.5]
    at org.postgresql.jdbc.PgStatement.executeInternal(PgStatement.java:441) ~[postgresql-42.2.5.jar:42.2.5]
    at org.postgresql.jdbc.PgStatement.execute(PgStatement.java:365) ~[postgresql-42.2.5.jar:42.2.5]
    at org.postgresql.jdbc.PgStatement.executeWithFlags(PgStatement.java:307) ~[postgresql-42.2.5.jar:42.2.5]
    at org.postgresql.jdbc.PgStatement.executeCachedSql(PgStatement.java:293) ~[postgresql-42.2.5.jar:42.2.5]
    at org.postgresql.jdbc.PgStatement.executeWithFlags(PgStatement.java:270) ~[postgresql-42.2.5.jar:42.2.5]
    at org.postgresql.jdbc.PgStatement.execute(PgStatement.java:266) ~[postgresql-42.2.5.jar:42.2.5]
    at com.zaxxer.hikari.pool.ProxyStatement.execute(ProxyStatement.java:95) ~[HikariCP-3.2.0.jar:na]
    at com.zaxxer.hikari.pool.HikariProxyStatement.execute(HikariProxyStatement.java) ~[HikariCP-3.2.0.jar:na]
    at org.hibernate.tool.schema.internal.exec.GenerationTargetToDatabase.accept(GenerationTargetToDatabase.java:54) ~[hibernate-core-5.3.10.Final.jar:5.3.10.Final]
    ... 34 common frames omitted

Student.java

@Builder
@AllArgsConstructor
@NoArgsConstructor
@Entity
@Table(uniqueConstraints = {
        @UniqueConstraint(name="student_name_key",columnNames = {"studentName"})
})
public class Student extends AuditEntity{
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "student_id")
    private Long studentId;

    @Column(name = "studentName", nullable = false)
    private String studentName;

    @Builder(builderMethodName = "sBuilder")
    public Student(String studentName, Instant createdDate, Instant lastUpdateDate, String createUser, 
            String lastUpdateUser, String status) {
        super(createdDate, lastUpdateDate, createUser, lastUpdateUser, status);
        this.studentName = studentName;
    }
}

AuditEntity.java

@Data
@NoArgsConstructor
@AllArgsConstructor
@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
public class AuditEntity {
    @CreatedDate
    @Column(name = "createdDate", nullable = false, updatable = false, columnDefinition = "TIMESTAMP WITHOUT TIME ZONE DEFAULT CURRENT_TIMESTAMP")
    private Instant createdDate;

    @LastModifiedDate
    @Column(name = "lastUpdateDate", nullable = false, columnDefinition = "TIMESTAMP WITHOUT TIME ZONE")
    private Instant lastUpdateDate;

    @Column(name = "createUser", nullable = false, length = 30)
    private String createUser;

    @Column(name = "lastUpdateUser", length = 30)
    private String lastUpdateUser;

    @Column(name = "status", length = 1, columnDefinition = "ENUM('A', 'I')")
    private String status;
}

MainApp.java

@SpringBootApplication
public class MainApp implements CommandLineRunner {
    @Autowired
    ProgramRepository programRepository;

    public static void main(String[] args) {
        SpringApplication.run(MainApp.class, args);
    }

    @Override
    public void run(String... args) throws Exception {
        Student student = Student.sBuilder().studentName("John Doe").createUser("ABC")
            .createdDate(Instant.now()).lastUpdateDate(Instant.now()).lastUpdateUser("XYZ").build();
    programRepository.save(student);
    }
}

注意:我真的希望对private String status;施加约束以接受A或I。除此以外的任何值都不允许。如果我删除columnDefinition = "ENUM('A', 'I')",那么一切正常。为什么?

这是一个错误吗?

3 个答案:

答案 0 :(得分:2)

创建一个ENUM并按以下方式使用:


@Data
@NoArgsConstructor
@AllArgsConstructor
@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
public class AuditEntity {

    public static enum Status {
A, I
}


    @CreatedDate
    @Column(name = "createdDate", nullable = false, updatable = false, columnDefinition = "TIMESTAMP WITHOUT TIME ZONE DEFAULT CURRENT_TIMESTAMP")
    private Instant createdDate;

    @LastModifiedDate
    @Column(name = "lastUpdateDate", nullable = false, columnDefinition = "TIMESTAMP WITHOUT TIME ZONE")
    private Instant lastUpdateDate;

    @Column(name = "createUser", nullable = false, length = 30)
    private String createUser;

    @Column(name = "lastUpdateUser", length = 30)
    private String lastUpdateUser;

    @Column(name = "status")
    @Enumerated(EnumType.STRING)
    private Status status;
}


答案 1 :(得分:0)

我认为这是您需要的:

CREATE TYPE month AS ENUM ('January', 'February', 'March', 'and so on...');

CREATE TABLE magazine(
  id serial PRIMARY KEY,
  title text NOT NULL,
  issue_month month,
  issue_year integer
);

Check out this post for more:)

答案 2 :(得分:0)

可能会对您有所帮助

@Entity(name = "Post")
@Table(name = "post")
@TypeDef(
    name = "pgsql_enum",
    typeClass = PostgreSQLEnumType.class
)
public class Post {

    @Id
    private Long id;

    private String title;

    @Enumerated(EnumType.STRING)
    @Column(columnDefinition = "post_status_info")
    @Type( type = "pgsql_enum" )
    private PostStatus status;

    //Getters and setters omitted for brevity
}

for more ref...