【问题标题】:Hibernate Exception: java.lang.IllegalArgumentException: Unknown name value [] for enum class休眠异常:java.lang.IllegalArgumentException:枚举类的未知名称值 []
【发布时间】:2013-10-27 06:40:11
【问题描述】:

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

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)

【问题讨论】:

  • 数据库不能修复,无效值设置空值?
  • 它可以修复,但它涉及大量的手动工作,我还必须确保它不会破坏使用数据库的其他应用程序。因此,如果休眠中有一种方法可以抑制这些异常并将其设置为 null,那将是非常有帮助的?

标签: java mysql hibernate enums hibernate-mapping


【解决方案1】:

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

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

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

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

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

【讨论】:

    【解决方案2】:

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

    enum SomeEnum {A, B, C}
    

    为它创建一个自定义类型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;
      }
    

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

    @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;
    

    【讨论】:

      猜你喜欢
      • 2013-07-03
      • 2015-07-28
      • 2014-08-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多