# ClassCastException with enums in REST server application

**URL:** <https://discourse.hibernate.org/t/classcastexception-with-enums-in-rest-server-application/9686>\
**Category:** Hibernate ORM\
**Created:** [June 3, 2024, 3:31pm UTC](https://discourse.hibernate.org/t/classcastexception-with-enums-in-rest-server-application/9686 "2024-06-03T15:31:56Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![t\_heit](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.hibernate.org/t_heit/32/2855_2.png) [@t\_heit](https://discourse.hibernate.org/u/t_heit)\
**Post date:** [June 3, 2024, 3:31pm UTC](https://discourse.hibernate.org/t/classcastexception-with-enums-in-rest-server-application/9686/1 "2024-06-03T15:31:56Z")

</div>

I’m facing a strange error in a REST server application when trying to store an entity instance in a database:

The entity contains a map with enums as keys and strings as values. Both the entity and the enum class come from generated code via an OpenAPI YAML file; I only added a few annotations such as @Entity, @Id, @ElementCollection etc. so that I’m able to store and retrieve data via Hibernate. So far, so good, calling my REST server code to store and retrieve instances via the REST interface works.

When I add the Jackson databind annotations @JsonSerialize to the entity map’s getter method and @JsonDeserialize to the corresponding setter method to use a custom (de-)serializer for the map values, storing an entity instance in my server code now fails in its database layer:

```auto
java.lang.ClassCastException: class java.lang.Integer cannot be cast to class java.lang.Enum (java.lang.Integer and java.lang.Enum are in module java.base of loader 'bootstrap')
	at org.hibernate.type.descriptor.java.EnumJavaType.unwrap(EnumJavaType.java:36)
	at org.hibernate.type.descriptor.jdbc.TinyIntJdbcType$1.doBind(TinyIntJdbcType.java:75)
	at org.hibernate.type.descriptor.jdbc.BasicBinder.bind(BasicBinder.java:61)
	at org.hibernate.engine.jdbc.mutation.internal.JdbcValueBindingsImpl.lambda$beforeStatement$0(JdbcValueBindingsImpl.java:87)
	at java.base/java.lang.Iterable.forEach(Iterable.java:75)
	at org.hibernate.engine.jdbc.mutation.spi.BindingGroup.forEachBinding(BindingGroup.java:51)
	at org.hibernate.engine.jdbc.mutation.internal.JdbcValueBindingsImpl.beforeStatement(JdbcValueBindingsImpl.java:85)
	at org.hibernate.engine.jdbc.mutation.internal.AbstractMutationExecutor.performNonBatchedMutation(AbstractMutationExecutor.java:130)
	at org.hibernate.engine.jdbc.mutation.internal.MutationExecutorSingleNonBatched.performNonBatchedOperations(MutationExecutorSingleNonBatched.java:55)
	at org.hibernate.engine.jdbc.mutation.internal.AbstractMutationExecutor.execute(AbstractMutationExecutor.java:55)
	at org.hibernate.persister.collection.mutation.InsertRowsCoordinatorStandard.insertRows(InsertRowsCoordinatorStandard.java:117)
	at org.hibernate.persister.collection.BasicCollectionPersister.recreate(BasicCollectionPersister.java:119)
	at org.hibernate.action.internal.CollectionRecreateAction.execute(CollectionRecreateAction.java:47)
	at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:632)
	at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:499)
	at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:371)
	at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:41)
	at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:127)
	at org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1425)
	at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:487)
	at org.hibernate.internal.SessionImpl.flushBeforeTransactionCompletion(SessionImpl.java:2324)
	at org.hibernate.internal.SessionImpl.beforeTransactionCompletion(SessionImpl.java:1981)
	at org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.beforeTransactionCompletion(JdbcCoordinatorImpl.java:439)
	at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.beforeCompletionCallback(JdbcResourceLocalTransactionCoordinatorImpl.java:169)
	at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.commit(JdbcResourceLocalTransactionCoordinatorImpl.java:267)
	at org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:101)
	at org.hibernate.internal.TransactionManagement.commit(TransactionManagement.java:65)
	at org.hibernate.internal.TransactionManagement.manageTransaction(TransactionManagement.java:23)
	at org.hibernate.SessionFactory.lambda$inTransaction$0(SessionFactory.java:237)
	at org.hibernate.SessionFactory.inSession(SessionFactory.java:217)
	at org.hibernate.SessionFactory.inTransaction(SessionFactory.java:237)
	at com.example.DatabaseManager.insert(DatabaseManager.java:235)
(...)

```

Store method in my database layer:

```java
public <T> void insert(T data) throws PersistenceException {
	try {
		this.sessionFactory.inTransaction(session -> session.persist(data));
	} catch (Exception ex) {
		throw new PersistenceException("Error saving object", ex);
	}
}

```

Enum class:

```java
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonValue;

public enum MyEnum {
	ONE(1), TWO(2), THREE(3);

	private Integer value;

	MyEnum(Integer value) {
		this.value = value;
	}

	public static MyEnum fromString(String s) {
		for (MyEnum b : MyEnum.values()) {
			if (java.util.Objects.toString(b.value).equals(s)) {
				return b;
			}
		}
		throw new IllegalArgumentException("Unexpected string value '" + s + "'");
	}

	@Override
	@JsonValue
	public String toString() {
		return String.valueOf(value);
	}

	@JsonCreator
	public static MyEnum fromValue(Integer value) {
		for (MyEnum b : MyEnum.values()) {
			if (b.value.equals(value)) {
				return b;
			}
		}
		throw new IllegalArgumentException("Unexpected value '" + value + "'");
	}
}

```

Entity class:

```java
@Entity
public class MyEntity {
	private @Valid @Id @GeneratedValue Long id;

	private @ElementCollection(fetch = FetchType.EAGER) Map<MyEnum, String> data;

	public Long getId() {
		return id;
	}

	public void setId(Long pId) {
		this.id = pId;
	}

	@JsonProperty("data")
	// @JsonSerialize(using = MapToArraySerializer.class)
	public Map<MyEnum, String> getData() {
		return this.data;
	}

	@JsonProperty("data")
	// @JsonDeserialize(using = ArrayToMapDeserializer.class)
	public void setData(Map<MyEnum, String> pData) {
		this.data = pData;
	}

	public void addData(MyEnum key, String value) {
		if (null == this.data) {
			this.data = new HashMap<>();
		}
		this.data.put(key, value);
	}
}

```

I’ve verified this via a JUnit test that starts up the REST server code before any tests are executed.

What puzzles me:

Annotations are uncommented:

- The unit test calls the insert method in the database layer directly =\> works
- The unit test triggers a REST API call so that the server code tries to insert the entity =\> exception

Annotations are commented out:  
Inserting works in both cases.

Do you have any idea what I’m doing wrong and/or what is causing this behaviour?

Environment:  
Hibernate ORM: 6.5.2.Final  
RESTeasy 6.2.9.Final  
Java 21  
Database: PostgreSQL 16.2

Regards

Thorsten

PS: The above mentioned server application code is a simulator for a custom program we have to call via an OpenAPI REST interface. Although the API description says that the entity’s field is a map, the custom program implementation assumes it to be an array (!) with entries [key\_1, value\_1, …, key\_n, value\_n] with key\_X/value\_x being the data from map entry #X…

---

<div class="post-metadata">

**Author:** ![beikov](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.hibernate.org/beikov/32/258_2.png) [@beikov](https://discourse.hibernate.org/u/beikov)\
**Post date:** [June 4, 2024, 2:04pm UTC](https://discourse.hibernate.org/t/classcastexception-with-enums-in-rest-server-application/9686/2 "2024-06-04T14:04:53Z")

</div>

AFAICT from the description, it seems to me that Jackson deserializes something into that `Map` field which is not a `Map<MyEnum, String>`, but rather `Map<Integer, String>`, so your `ArrayToMapDeserializer` probably does something wrong. Note that generics in Java are erased.

---

<div class="post-metadata">

**Author:** ![t\_heit](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.hibernate.org/t_heit/32/2855_2.png) [@t\_heit](https://discourse.hibernate.org/u/t_heit)\
**Post date:** [June 4, 2024, 3:02pm UTC](https://discourse.hibernate.org/t/classcastexception-with-enums-in-rest-server-application/9686/3 "2024-06-04T15:02:30Z")

</div>

D’oh! You’re right, the deserializer indeed created Integer objects as keys instead of the enum instances. I was so sure that this wasn’t the case because I inspected the map in my debugger and had a look at the entries but overlooked that the string representation didn’t show the class type…

Thanks for helping me with this!
