2010-11-22 19 views
5

estoy usando una enumeración en mi modelo de dominio, pero me sale el siguiente error cuando trato de persistir un objeto a la base de datos:Cómo persistir un objeto que tiene un campo de enumeración

 
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) 

Este es mi modelo de dominio:

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(); 
    } 
} 

¿Por qué no es la anotación @Enumerated trabajar como creo que debería estar trabajando? Y si está funcionando como debería, ¿cómo puedo hacer que funcione de la manera que ahora creo que está funcionando? O en otras palabras: cómo persistir un objeto que tiene un campo de enumeración.

EDITAR: Gracias por todas las respuestas. El NotEmpty está allí por accidente, no lo vi. Tuve que hacer muchas asignaciones, así que copié y pegué muchas cosas, pero accidentalmente olvidé eliminar el NotEmpty cuando cambié de cadena a enumeración. La próxima vez que trate de mirar más de cerca a la pila de fichas, extrañé totalmente ese NotEmptyValidator.

+0

tenemos los StackTrace completa, por favor. – axtavt

+1

Proporcione un SSCCE. BTW, Enum_WhifFunction no sigue las convenciones de nomenclatura de Java. Recomiendo deshacerse del guión bajo. – Puce

+0

Se agregó stacktrace. – FinalArt2005

Respuesta

4

¡El problema es que el validador no es el mapeo!

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

la anotación @NotEmpty contiene @Size(min = 1) y @Size sólo admite cuerdas, Colección, mapa y Array.

+1

Reemplace @NotEmpty por @NotNull – Ralph

0

Podría ser útil echar un vistazo a Mapping enum types with Hibernate Annotations.

A partir del ejemplo no parece que usted debe tener:

private Enum_WhifFunction   whifFunction; 
@Enumerated(EnumType.STRING) 
public Enum_WhifFunction getWhifFunction() { 
    return this.whifFunction; 
} 
+0

¿Cómo es lo que muestran allí diferente de lo que tengo aquí? Aún en mi código, no parece estar funcionando. Voy a probar EnumType.ORDINAL cuando llegue a casa para ver si eso podría ser el truco. Sin embargo, me gustaría que las representaciones en cadena de las enumeraciones estén en la base de datos, y no en números, en caso de que un humano esté buscando directamente en la base de datos. – FinalArt2005

0

Al parecer Enum_WhifFunction no se puede convertir en una cadena. ¿Puedes publicar el código Enum_WhifFunction?

1

java.lang.ClassCastException: nl.ru.cmbi.pdbeter.core.model.enums.Enum_WhifFunction no puede convertirse a java.lang.String en org.hibernate.validator.NotEmptyValidator.isValid (NotEmptyValidator. java: 36)

@NotEmpty parece ser la fuente de la probelem no la anotación @Enumerated ...

2

creo que si cambia @NotEmpty a @NotNull que debería funcionar. NotEmpty mediante una cadena debe ser igual a:

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

Usando @Enumerated con cadena debe persistir Enum_WhifFunction.name() como el valor db almacenado, por lo que por el contrario se debe hacer Enum_WhifFunction.valuOf(storedValue) para transferir el valor de cadena de nuevo a la enumeración.

El problema probablemente se produce debido a que el validador es probable tratando de hacer algo como esto:

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; 
Cuestiones relacionadas