0

I've now wasted several hours trying to get this to work, but Hibernate still keeps me wondering what's going on there inside.
Here's what I want to do:
Simply persist a List of enums via @Enumerated which looks like this:

@LazyCollection(LazyCollectionOption.FALSE)
@ElementCollection(targetClass=Role.class)
@JoinTable(name = "userroles", joinColumns = @JoinColumn(name = "userId"))
@Enumerated(EnumType.ORDINAL)
private List<Role> roles;

My enum class:

public enum Role implements Serializable {
    employee("Mitarbeiter"),
    manager("Geschäftsleitung"),
    stationleader("Stationsleitung"),
    administration("Verwaltung"),
    accountant("Buchhaltung");
@Transient
private String description;

private Role()
{

}

public void setDescription(String description) {
    this.description = description;
}

private Role(String desc) {
    this.description = desc;
}

@Override
public String toString() {
    return description;
}

public String getDescription() {
    return description;
}   
}

The error I'm encountering occurs at a simple persist() of the class which is holding the List. And it's root cause is:

Caused by: java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Enum
at org.hibernate.type.EnumType.nullSafeSet(EnumType.java:118) [hibernate-core-4.0.1.Final.jar:4.0.1.Final]
at org.hibernate.type.CustomType.nullSafeSet(CustomType.java:155) [hibernate-core-4.0.1.Final.jar:4.0.1.Final]
at org.hibernate.persister.collection.AbstractCollectionPersister.writeElement(AbstractCollectionPersister.java:811) [hibernate-core-4.0.1.Final.jar:4.0.1.Final]
at org.hibernate.persister.collection.AbstractCollectionPersister.recreate(AbstractCollectionPersister.java:1201) [hibernate-core-4.0.1.Final.jar:4.0.1.Final]
at org.hibernate.action.internal.CollectionRecreateAction.execute(CollectionRecreateAction.java:58) [hibernate-core-4.0.1.Final.jar:4.0.1.Final]
at org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:272) [hibernate-core-4.0.1.Final.jar:4.0.1.Final]
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:264) [hibernate-core-4.0.1.Final.jar:4.0.1.Final]
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:190) [hibernate-core-4.0.1.Final.jar:4.0.1.Final]
at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:326) [hibernate-core-4.0.1.Final.jar:4.0.1.Final]
at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:52) [hibernate-core-4.0.1.Final.jar:4.0.1.Final]
at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1081) [hibernate-core-4.0.1.Final.jar:4.0.1.Final]
at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:315) [hibernate-core-4.0.1.Final.jar:4.0.1.Final]
at org.hibernate.engine.transaction.synchronization.internal.SynchronizationCallbackCoordinatorImpl.beforeCompletion(SynchronizationCallbackCoordinatorImpl.java:104) [hibernate-core-4.0.1.Final.jar:4.0.1.Final]

How could I resolve this? There doesn't seem to be any known bugs of this and I just found non-answered threads in several forums. I also tried EnumType.STRING and leaving some of the annotations, without effect though :/
EDIT: I also tried to just use a raw enum with standard constructor and no fields, nothing but the values. So the error must not lie in my enum-pojo.
EDIT2:
My problem lied a bit elsewhere. (JSF and type safety). However I will accept the answer how pushed me in the right direction :)

Community
  • 1
  • 1
Zhedar
  • 3,480
  • 1
  • 21
  • 44
  • Try converting your enum names to uppercase. If that doesn't help, set the logger level to TRACE and post the log here. – Marlon Bernardes May 08 '13 at 02:20
  • @MarlonBernardes Converting to uppercase didn't change a thing. It also doesn't seem to work setting `Logger log = Logger.getLogger("org.hibernate.SQL"); log.setLevel(Level.TRACE);` as I don't see more log entrys than before. (1 Info) – Zhedar May 08 '13 at 02:45
  • Use "org.hibernate.type" instead of "org.hibernate.SQL". Don't set it manually, it must be configured before application startup (eg.: log4j.properties -> log4j.logger.org.hibernate.type=TRACE) – Marlon Bernardes May 08 '13 at 02:52
  • Well, still there's only one thing getting printed and that's `INFO [org.hibernate.engine.jdbc.batch.internal.AbstractBatchImpl] (http-localhost-127.0.0.1-8080-3) HHH000010: On release of batch it still contained JDBC statements` within those exceptions. It's hibernate 4.2.1Final – Zhedar May 08 '13 at 02:58

1 Answers1

1

As your Enum have custom attributes you have some options:

  1. Create your custom type (UserType) as follows: https://community.jboss.org/wiki/UserTypeforpersistingaTypesafeEnumerationwithaVARCHARcolumn
  2. Create your Enum property as a transiente and use a String getter and setter to populate.
Mohsen Heydari
  • 7,256
  • 4
  • 31
  • 46
br araujo
  • 1,856
  • 2
  • 13
  • 14
  • I already tried that. I wanted to explain that in the section below. But now I see I wrote ORDINAL there, too :/ Actually `String` was the first thing I tried. – Zhedar May 08 '13 at 02:48
  • What exception you got when you used String? – br araujo May 08 '13 at 02:49
  • Wouldn't 3 be the case when I tested it with a raw `enum`(no properties)? Because that's what I already did and that sadly didn't work out. The 1st would probably the best solution, but it seems so overcomplicated. – Zhedar May 08 '13 at 03:08
  • With a raw enum it must work. If didn't we will need to check your database structure. – br araujo May 08 '13 at 03:11
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/29570/discussion-between-zhedar-and-br-araujo) – Zhedar May 08 '13 at 03:17