5

I'm using an enumeration in my domain model, but I get the following error when I try to persist an object to the database:

Exception in thread "main" java.lang.ClassCastException: nl.ru.cmbi.pdbeter.core.model.enums.Enum_WhifFunction cannot be cast to java.lang.String
    at org.hibernate.validator.NotEmptyValidator.isValid(NotEmptyValidator.java:36)
    at org.hibernate.validator.ClassValidator.getInvalidValues(ClassValidator.java:386)
    at org.hibernate.validator.ClassValidator.getInvalidValues(ClassValidator.java:352)
    at org.hibernate.validator.event.ValidateEventListener.validate(ValidateEventListener.java:139)
    at org.hibernate.validator.event.ValidateEventListener.onPreInsert(ValidateEventListener.java:172)
    at org.hibernate.action.EntityIdentityInsertAction.preInsert(EntityIdentityInsertAction.java:142)
    at org.hibernate.action.EntityIdentityInsertAction.execute(EntityIdentityInsertAction.java:65)
    at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:279)
    at org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:321)
    at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:204)
    at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:130)
    at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:210)
    at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:195)
    at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:117)
    at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:93)
    at org.hibernate.impl.SessionImpl.fireSaveOrUpdate(SessionImpl.java:535)
    at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:527)
    at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:523)
    at nl.ru.cmbi.pdbeter.core.controller.DAO.GenericDAO.makePersistent(GenericDAO.java:73)
    at nl.ru.cmbi.pdbeter.core.controller.DAO.WhifFunctionDAO.getWhifFunctionSet(WhifFunctionDAO.java:36)
    at nl.ru.cmbi.pdbeter.core.controller.DAO.LoggedErrorWhifDAO.updateWhifFunctionSet(LoggedErrorWhifDAO.java:42)
    at nl.ru.cmbi.pdbeter.whifclient.controller.WhifFunctionsUpdater.executeWhifFunctionsByAccessionCode(WhifFunctionsUpdater.java:93)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:616)
    at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:309)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:110)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
    at $Proxy31.executeWhifFunctionsByAccessionCode(Unknown Source)
    at nl.ru.cmbi.pdbeter.whifclient.controller.WhifFunctionsExecutor.executeWhifFunctions(WhifFunctionsExecutor.java:26)
    at nl.ru.cmbi.pdbeter.whifclient.controller.WhifClient.updateWhifFunctions(WhifClient.java:22)
    at nl.ru.cmbi.pdbeter.updater.controller.UpdaterMain.start(UpdaterMain.java:65)
    at nl.ru.cmbi.pdbeter.updater.controller.UpdaterMain.main(UpdaterMain.java:44)

This is my domain model:

package nl.ru.cmbi.pdbeter.core.model.domain;

import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.ManyToMany;

import lombok.AccessLevel;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;

import nl.ru.cmbi.pdbeter.core.model.enums.Enum_WhifFunction;

import org.hibernate.annotations.NaturalId;
import org.hibernate.validator.NotEmpty;

@Entity
@Data
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@EqualsAndHashCode(callSuper = false, of = { "whifFunction" })
@SuppressWarnings("PMD.UnusedPrivateField")
public class WhifFunction extends DomainObject implements Serializable {
    @NaturalId
    @NotEmpty
    @Enumerated(EnumType.STRING)
    private Enum_WhifFunction           whifFunction;

    @ManyToMany(mappedBy = "whifFunctionSet", cascade = CascadeType.ALL)
    private Set<LoggedErrorWhif> loggedErrorWhifSet = new HashSet<LoggedErrorWhif>();

    public WhifFunction(Enum_WhifFunction whifFunction) {
        if (whifFunction == null) {
            throw new IllegalStateException("WhifFunction is null");
        } else {
            this.whifFunction = whifFunction;
        }
    }

    @Override
    public String toString() {
        return whifFunction.toString();
    }
}

Why isn't the @Enumerated annotation working as I think it should be working? And if it is working as it is supposed to, how can I make it work the way I now think it is working? Or in other words: how to persist an object that has an enumeration field.

EDIT: Thanks for all the answers. The NotEmpty is there by accident, I didn't see it. I had to make a lot of mappings so I copy-pasted a lot of stuff, but accidentally forgot to remove the NotEmpty when I changed from string to enum. Next time I'll try to look more closely to the stacktrace, I totally missed that NotEmptyValidator.

Erik Stens
  • 1,779
  • 6
  • 25
  • 40

5 Answers5

4

The problem is the validator not the mapping!

at org.hibernate.validator.NotEmptyValidator.isValid(NotEmptyValidator.java:36)

The Annotation @NotEmpty contains @Size(min = 1) and @Size supports only String, Collection, Map and Array.

Anton N
  • 2,317
  • 24
  • 28
Ralph
  • 118,862
  • 56
  • 287
  • 383
2

I think if you change @NotEmpty to @NotNull it should work. NotEmpty using a String should equate to:

string != null && string.trim().length() > 0

Using @Enumerated with String should persist Enum_WhifFunction.name() as the stored db value, so conversely it should do Enum_WhifFunction.valuOf(storedValue) to transfer the string value back to the enumeration.

The problem likely occurs because the validator is likely attempting to do something like this:

Object o = //get field
String toValidate = (String) o; // throws a class cast if o is of type Enum_WhifFunction
return toValidate != null && toValidate.trim().length() > 0;
hisdrewness
  • 7,599
  • 2
  • 21
  • 28
1

java.lang.ClassCastException: nl.ru.cmbi.pdbeter.core.model.enums.Enum_WhifFunction cannot be cast to java.lang.String at org.hibernate.validator.NotEmptyValidator.isValid(NotEmptyValidator.java:36)

@NotEmpty seems to be the source of the probelem not the @Enumerated annotation...

Puce
  • 37,247
  • 13
  • 80
  • 152
0

It might help to take a look at Mapping enum types with Hibernate Annotations.

From the example there it looks like you should have:

private Enum_WhifFunction           whifFunction;
@Enumerated(EnumType.STRING)
public Enum_WhifFunction getWhifFunction() {
  return this.whifFunction;
}
Community
  • 1
  • 1
Dave Costa
  • 47,262
  • 8
  • 56
  • 72
  • How is what they show there different from what I have here? Still in my code it doesn't seem to be working. I'll try EnumType.ORDINAL when I get home to see if that might do the trick. Still I'd like for the string representations of the enums to be in the database, and not numbers, in case a human is looking in the database directly. – Erik Stens Nov 22 '10 at 16:30
0

Apparently Enum_WhifFunction cannot be cast to a String. Can you post the Enum_WhifFunction code?

Uberto
  • 2,712
  • 3
  • 25
  • 27