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

Accepted answer
Score: 53

This worked for me...

My Spring application 10 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 9 important things to note are that in the 8 Spring context I used SpEL (Spring Expression 7 Language) which is only available since 6 version 3.0. And in my class I used @Resource, neither 5 @Inject (it didn't work for me) nor @Autowired (I didn't 4 try this). The only difference I'm aware 3 of between @Resource and @Autowired, is that the former auto-inject 2 by bean name while the later does it by 1 bean type.

Enjoy!

Score: 18

This one gave me fits but I was able to 2 piece it together using David's answer and 1 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

Score: 5

Application context

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:util="http://www.springframework.org/schema/util"
       xsi:schemaLocation="http://www.springframework.org/schema/beans  http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
            http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.1.xsd ">

<bean id="myProvider" class="com.project.MapProvider">
    <property name="myMap" ref="myMap"/>
</bean>

<util:map id="myMap" key-type="com.project.MyEnum" value-type="com.project.ValueObject">
    <entry>
        <key><value type="com.project.MyEnum">FOO</value></key>
        <ref bean="objectValue1"/>
    </entry>
</util:map>
</beans>

Java class

package com.project;

public class MapProvider {

    private Map<MyEnum, ValueObject> myMap;

    public void setMyMap(Map<MyEnum, ValueObject> myMap) {
        this.myMap = myMap;
    }
}

0

Score: 1

Should be:

public class Mick {

  private Map<MyEnum, OtherObj> myMap;

  @Autowired
  public void setMyMap(Map<MyEnum, OtherObj> myMap) {
    this.myMap = myMap;
  }
}

Have a look at http://static.springsource.org/spring/docs/2.5.x/reference/beans.html#beans-annotation-config

Updated

The problem is 7 that according to the util schema, you cannot 6 specify the key or value types. You can 5 however to implement a MapFactoryBean of 4 your own (just inherit from org.springframework.beans.factory.config.MapFactoryBean). One 3 ceveat - notice that the generic definition 2 (even thought erased in runtime) doesn't 1 get in the way.

Score: 0

The <util:map> element has key-type, resp. value-type 11 attributes, that represents the class of 10 the keys, resp. the values. If you specify 9 the fully qualified class of your enum in 8 the key-type attribute, the keys are then 7 parsed into that enum when creating the 6 map.

Spring verifies during injection that 5 the map's key and value types -as declared 4 in the class containing the map- are assignment-compatible 3 with the key and value types of the map 2 bean. This is actually where you get the 1 exception from.

Score: 0

You just need to use concrete Map class as 1 HashMap and not abstract or interface:

public class Mick {

  private HashMap<MyEnum, OtherObj> myMap;

  @Autowired
  public void setMyMap(HashMap<MyEnum, OtherObj> myMap) {
    this.myMap = myMap;
  }
}


public class AppConfig
{
    @Bean
    public HashMap<MyEnum, OtherObj> myMap() { .. }
}
Score: 0

If you have a Map with an Enum values as keys, then 3 consider using Java's EnumMap implementation:

https://docs.oracle.com/en/java/javase/12/docs/api/java.base/java/util/EnumMap.html

Here 2 you also have a Baeldung post with some 1 examples on how to use it:

https://www.baeldung.com/java-enum-map

More Related questions