Search code examples
javahibernateormhibernate-mappinghibernate-5.x

Is it possible to create a one-to-one mapping with the columns as keys for a hashmap?


Imagine I have the following class where all the fields are integers:

@Entity
public class Bar implements Serializable { 
    @Id
    private Integer id;

    @Basic
    private Integer field1;

    @Basic
    private Integer field2;

    //Constructor & getters/setters omitted
}

Now I wish to have another class Foo which has a HashMap where the keys are fields in Bar with the corresponding values. I.e., something like this:

@Entity
public class Foo implements Serializable {
   @Id
   private Integer id;

   @Basic
   private String someString;

   @Basic
   private Integer someInteger;

   @??
   private HashMap<String, Integer> barMap;

   //Constructor & getters/setters omitted

The reason behind doing this is that I have an an underlying Enum, each value of the Enum should be a column, and then after fetching this as a Map I would have easy access to every field because I already know the names of the properties.

In my mind, the underlying tables would look something like this: Link to image, as I am not allowed to embed yet.

Is something like this possible? What kind of annotation would it require? I previously tried something as follows in Foo, but it reports that a One-To-One attribute should not be used as a map, so I am probably thinking about this the wrong way.

@OneToOne(mappedBy="Bar")
@MapKey(name="Id")
private HashMap<String, Integer> barMap;

Solution

  • To any future visitors:

    I could not find any way to pull this off, and I realized it was probably because it is not good design/practice. Instead, I ended up redesigning my Bar class so that its fields were now the enum and the value, basically transposing the table. The Foo class then simply has a Map<Enum, Bar>. The annotations are:

    Foo:

    @OneToMany(mappedBy="fooInstance", cascade = CascadeType.ALL)
    @MapKey(name="enumField")
    private Map<EnumType, Bar> barMap;
    

    Bar:

    @Id
    @Column(name = "id", unique = true, nullable = false)
    @GeneratedValue(strategy = GenerationType.SEQUENCE)
    private Integer id;
    
    @Column(name="enumField", nullable = false)
    @Enumerated(EnumType.ORDINAL)
    private EnumType enumField;
    
    @Basic
    @Column(name="myField")
    private int myField = 0;
    
    @ManyToOne
    @JoinColumn(name="fooInstance", nullable = false)
    private Foo fooInstance;