2010-11-22 2 views
5

Я использую перечисление в моей модели домена, но я получаю следующее сообщение об ошибке при попытке сохранить объект в базу данных:Как сохранить объект, который имеет поле перечисления

 
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) 

Это моя модель домена:

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

Почему не @Enumerated аннотаций работает, как я думаю, что это должно работать? И если он работает так, как предполагается, как я могу заставить его работать так, как я теперь думаю, что он работает? Или другими словами: как сохранить объект, который имеет поле перечисления.

EDIT: Спасибо за все ответы. NotEmpty там случайно, я этого не видел. Мне пришлось сделать много сопоставлений, поэтому я скопировал много вещей, но случайно забыл удалить NotEmpty, когда я перешел из строки в enum. В следующий раз, когда я попытаюсь более внимательно рассмотреть стек, я полностью пропустил этот NotEmptyValidator.

+0

Показать полный StackTrace, пожалуйста. – axtavt 2010-11-22 16:20:09

+1

Пожалуйста, предоставьте SSCCE. BTW, Enum_WhifFunction не соответствует соглашениям об именах Java. Я рекомендую избавиться от подчеркивания. – Puce 2010-11-22 16:26:30

+0

Добавлен стек. – FinalArt2005 2010-11-22 16:31:09

ответ

4

Проблема - это валидатор, а не отображение!

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

@NotEmpty аннотацию содержит @Size(min = 1) и @Size поддерживает только String, Коллекция, карта и Array.

0

Это может помочь взглянуть на Mapping enum types with Hibernate Annotations.

Из примера там, похоже, вы должны иметь:

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

Видимо Enum_WhifFunction не может быть приведен к String. Можете ли вы опубликовать код Enum_WhifFunction?

1

java.lang.ClassCastException: nl.ru.cmbi.pdbeter.core.model.enums.Enum_WhifFunction не может быть приведен к java.lang.String на org.hibernate.validator.NotEmptyValidator.isValid (NotEmptyValidator. Java: 36)

@NotEmpty кажется источником probelem не @Enumerated аннотаций ...

2

Я думаю, что если вы измените @NotEmpty на @NotNull он должен работать. NotEmpty с помощью строки следует приравнивать к:

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

Использование @Enumerated с строки должны сохраняться Enum_WhifFunction.name() как сохраненное значение дб, так и наоборот он должен делать Enum_WhifFunction.valuOf(storedValue) передать значение строки обратно в перечислении.

Проблема, вероятно, происходит потому, что валидатор, вероятно, пытается сделать что-то вроде этого:

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;