Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring - How do you set Enum keys in a Map with annotations

I've an Enum class

public enum MyEnum{     ABC; } 

than my 'Mick' class has this property

private Map<MyEnum, OtherObj> myMap; 

I've this spring xml configuration.

<util:map id="myMap">     <entry key="ABC" value-ref="myObj" /> </util:map>  <bean id="mick" class="com.x.Mick">     <property name="myMap" ref="myMap" /> </bean> 

and this is fine.
I'd like to replace this xml configuration with Spring annotations.
Do you have any idea on how to autowire the map?

The problem here is that if I switch from xml config to the @Autowired annotation (on the myMap attribute of the Mick class) Spring is throwing this exception

nested exception is org.springframework.beans.FatalBeanException: Key type [class com.MyEnum] of map [java.util.Map] must be assignable to [java.lang.String] 

Spring is no more able to recognize the string ABC as a MyEnum.ABC object.
Any idea?

Thanks

like image 670
mickthompson Avatar asked Jul 23 '09 20:07

mickthompson


People also ask

Can we use Enum as map key?

In HashMap, we can use Enum as well as any other object as a key. It doesn't allow storing null key. It allows to store the null keys as well values, but there should be only one null key object and there can be any number of null values. HashMap internally uses the HashTable.

How do you add an Enum to a map?

EnumMap(Class keyType): The constructor is used to create an empty EnumMap with the specified keyType. EnumMap(Map m): The constructor is used to create an enum map with initialization from the specified map in the parameter.


2 Answers

This worked for me...

My Spring application context:

<util:map id="myMap">   <entry key="#{T(com.acme.MyEnum).ELEM1}" value="value1" />   <entry key="#{T(com.acme.MyEnum).ELEM2}" value="value2" /> </util:map> 

My class where the Map gets injected:

public class MyClass {      private @Resource Map<MyEnum, String> myMap; } 

The important things to note are that in the Spring context I used SpEL (Spring Expression Language) which is only available since version 3.0. And in my class I used @Resource, neither @Inject (it didn't work for me) nor @Autowired (I didn't try this). The only difference I'm aware of between @Resource and @Autowired, is that the former auto-inject by bean name while the later does it by bean type.

Enjoy!

like image 88
Cristian Ebbens Avatar answered Sep 30 '22 09:09

Cristian Ebbens


This one gave me fits but I was able to piece it together using David's answer and some other links (below).

  • do not change the names of the properties in the MapFactoryBean declaration.
  • ensure that key-type attribute points to the enum that you want to use as a key in the map.

Class

@Component public class MyClass {      private Map<MyEnum, ValueObjectInterface> valueMap;      @Autowired     public void setValueMap(final Map<MyEnum, ValueObjectInterface> valueMap) {         this.valueMap= valueMap;     }   } 

Enum

    public enum MyEnum{     FOO ("FOO"),     BAR ("BAR"),     BAZ ("BAZ"); } 

XML Config file:

<bean id="valueMap" class="org.springframework.beans.factory.config.MapFactoryBean">     <property name="targetMapClass">         <value>java.util.HashMap</value>     </property>     <property name="sourceMap">         <map key-type="com.company.packagepath.MyEnum">           <entry key="FOO" value-ref="valueObject1" />           <entry key="BAR" value-ref="valueObject2" />           <entry key="BAZ" value-ref="valueObject3" />         </map>     </property> </bean>  <bean id="valueObject1"  class="com.company.packagepath.ValueObject1" /> <bean id="valueObject2"  class="com.company.packagepath.ValueObject2" /> <bean id="valueObject3"  class="com.company.packagepath.ValueObject3" /> 

LINKS

  • Code Ranch
  • Spring MapFactoryBean example at mkyong.com
  • How assign bean's property an Enum value in Spring config file?
like image 44
Tony R Avatar answered Sep 30 '22 10:09

Tony R