休眠异常:java.lang.IllegalArgumentException:枚举类的未知名称值[]

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19449334/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 17:15:48  来源:igfitidea点击:

Hibernate Exception: java.lang.IllegalArgumentException: Unknown name value [] for enum class

javamysqlhibernateenumshibernate-mapping

提问by Bourne

I have mapped a column in Mysql DB to enum in java. But there are invalid entries in the table column (created manually) and which is not in the enum I created in java. When I try to load the entries I get the below exception. Is it possible to suppress this exception i.e. set the enum to 'null' when you have a invalid entry in the column in the Database?

我已将 Mysql DB 中的一列映射到 Java 中的 enum。但是表列中存在无效条目(手动创建)并且不在我在 java 中创建的枚举中。当我尝试加载条目时,出现以下异常。当您在数据库的列中有无效条目时,是否可以抑制此异常,即将枚举设置为“空”?

java.lang.IllegalArgumentException: Unknown name value [] for enum class [model.enums.PeriodUnit]
at org.hibernate.type.EnumType$NamedEnumValueMapper.fromName(EnumType.java:467)
at org.hibernate.type.EnumType$NamedEnumValueMapper.getValue(EnumType.java:452)
at org.hibernate.type.EnumType.nullSafeGet(EnumType.java:107)
at org.hibernate.type.CustomType.nullSafeGet(CustomType.java:127)
at org.hibernate.type.AbstractType.hydrate(AbstractType.java:106)
at org.hibernate.persister.entity.AbstractEntityPersister.hydrate(AbstractEntityPersister.java:2912)
at org.hibernate.loader.Loader.loadFromResultSet(Loader.java:1673)
at org.hibernate.loader.Loader.instanceNotYetLoaded(Loader.java:1605)
at org.hibernate.loader.Loader.getRow(Loader.java:1505)
at org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:713)
at org.hibernate.loader.Loader.processResultSet(Loader.java:943)
at org.hibernate.loader.Loader.doQuery(Loader.java:911)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:342)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:312)
at org.hibernate.loader.Loader.loadCollection(Loader.java:2238)
at org.hibernate.loader.collection.CollectionLoader.initialize(CollectionLoader.java:65)
at org.hibernate.persister.collection.AbstractCollectionPersister.initialize(AbstractCollectionPersister.java:674)
at org.hibernate.event.internal.DefaultInitializeCollectionEventListener.onInitializeCollection(DefaultInitializeCollectionEventListener.java:85)
at org.hibernate.internal.SessionImpl.initializeCollection(SessionImpl.java:1849)
at org.hibernate.collection.internal.AbstractPersistentCollection.forceInitialization(AbstractPersistentCollection.java:681)
at org.hibernate.engine.internal.StatefulPersistenceContext.initializeNonLazyCollections(StatefulPersistenceContext.java:1030)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:347)
at org.hibernate.loader.Loader.doList(Loader.java:2526)
at org.hibernate.loader.Loader.doList(Loader.java:2512)
at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2342)
at org.hibernate.loader.Loader.list(Loader.java:2337)
at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:495)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:357)
at org.hibernate.engine.query.spi.HQLQueryPlan.performList(HQLQueryPlan.java:195)
at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1269)
at org.hibernate.internal.QueryImpl.list(QueryImpl.java:101)

回答by Yurii Shylov

You have to specify your own hibernate type for this enum. Let's assume that you have enum

您必须为此枚举指定自己的休眠类型。让我们假设你有 enum

enum SomeEnum {A, B, C}

Create a custom type for it SomeEnumType implements UserType, ParameterizedType, you will have to implement a lot of methods, the one you are interested in is:

为它创建一个自定义类型SomeEnumType implements UserType, ParameterizedType,你将不得不实现很多方法,你感兴趣的是:

  @Override
  public Object nullSafeGet(ResultSet rs, String[] names, SessionImplementor session, Object owner)
      throws HibernateException, SQLException {
    Object result = null;
    try {
      String name = rs.getString(names[0]);
      if (!rs.wasNull()) {
        result = Enum.valueOf(clazz, name);
      }
    } catch (Exception e) {
      // result = null; // Here you handle incorrect database value
    }
    return result;
  }

In the end you map the column to the field of your entity:

最后,您将该列映射到实体的字段:

@Column(name = "some_enum", columnDefinition = "enum('A','B','C')")
@Type(type = "com.somepackage.SomeEnumType", parameters = @Parameter(name = "type", value = "com.somepackage.SomeEnumType"))
private SomeEnum someEnum;

回答by user1048931

I had a similar problem even though my field was correctly annotated with @Enumerated.

即使我的字段用@Enumerated 正确注释,我也遇到了类似的问题。

Issue was as follows - the schema DDL applied to the database defined the column type to be CHARACTER(5) whereas in the annotated hibernate entity it was defined as follows which defaults to VARCHAR.

问题如下 - 应用于数据库的模式 DDL 将列类型定义为 CHARACTER(5),而在带注释的休眠实体中,它定义如下,默认为 VARCHAR。

@Column
@Enumerated(EnumType.String)
private CustomEnumType customEnumType; 

I changed the database def in Postgres to be a VARCHAR for customEnumType. You can also try to change the metadata for the column by defining it as some other type and making the same change at the db level.

我将 Postgres 中的数据库定义更改为 customEnumType 的 VARCHAR。您还可以尝试通过将列定义为其他类型并在 db 级别进行相同更改来更改列的元数据。

In a nutshell, make sure your database table column definition matches up to what hibernate expects.

简而言之,请确保您的数据库表列定义符合 hibernate 的预期。