JPA: Is Map> possible?

I don’t see an example anywhere so I am not sure this is possible. But basically, I am trying to see if I can bind a field in an entity to

   Map<Skill,Set<Rating>> ratings;


CREATE TABLE Worker (
  ID         BIGINT PRIMARY KEY,

);

CREATE TABLE Skill (
  ID   BIGINT PRIMARY KEY,
  name VARCHAR(32) NOT NULL,
  UNIQUE (name)
);

CREATE TABLE WorkerSkillRating (
  ID       BIGINT PRIMARY KEY,
  WorkerID BIGINT NOT NULL,
  SkillID  BIGINT NOT NULL,
  Rating   INT,
  FOREIGN KEY (WorkerID) REFERENCES Worker (ID),
  FOREIGN KEY (SkillID) REFERENCES Skill (ID),
  FOREIGN KEY (Rating) REFERENCES Rating (ID)
);

CREATE TABLE Rating (
  ID       BIGINT PRIMARY KEY,
  score    TINYINT NOT NULL,
  comments VARCHAR(256)
);

Entities

@Entity
public class Skill {

    @Id
    private Long id;

    private String name;


    public Skill(String name) {
        this();
        this.name = name;
    }

    public Skill() {
        this.id = Math.abs( new Random().nextLong());
    }

}


@Entity
public class Worker {

    @Id
    private Long id;

    // The open question
    public Map<Skill, Set<Rating>> ratings;

}

@Entity
public class Rating {

    @Id
    private Long id;
    private Byte score;
    private String comments;

}

Answer

According to the JSR-0038 the JPA spec. When using Map, the following combination are just allowed: Basic Type, Entities and Embeddables.

Map<Basic,Basic> 
Map<Basic, Embeddable> 
Map<Basic, Entity>

Map<Embeddable, Basic> 
Map<Embeddable,Embeddable>
Map<Embeddable,Entity> 

Map<Entity, Basic>
Map<Entity,Embeddable>
Map<Entity, Entity> 

I don’t think there is pretty much deal to have a possible mapping in the way that you want but that is out of the specs and most of the providers follow them, I think that mapping is not very common at all.

“worker has many skills and he may have been given many ratings on a single skill. “

Then add to the skill class a Set<Ratings>, instead of nested directly in the map as the value of it.

Leave a Reply

Your email address will not be published. Required fields are marked *