How to map a Map in Hibernate

Asked

Viewed 132 times

2

I’m trying to map a diary to an apprentice, where in the diary I have a Map<data,mensagem>, that is, the date that was created and its respective message, but with the mapping that I did, I end up taking the following error:

Caused by: org.hibernate.MappingException: 
  Foreign key (FKr7nhfmr8w22h0h9ggc2oxd33r:aprendiz [diario_id])) must have same 
  number of columns as the referenced primary key (diario [id,data])

Apprentice Class:

@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public class Aprendiz extends Pessoa {

    @OneToOne(cascade = {CascadeType.ALL})
    private Diario diario;

    //get, set, hashcode...
}

Classe Diario

@Entity
public class Diario implements Serializable{
    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    @OneToOne(mappedBy = "diario")
    private Aprendiz aprendiz;

    @ElementCollection(fetch = FetchType.EAGER)
    @MapKeyColumn(name = "data")
    @Column(name = "texto")
    @CollectionTable(name = "diario", joinColumns = @JoinColumn(name = "id"))
    private Map<LocalDate, String> entrada = new HashMap<>();

        //get, set, hashcode...
}

1 answer

0

You can create a converter to convert the data so that JPA can interpret it:

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import javax.persistence.AttributeConverter;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

public class JpaConverterJson implements AttributeConverter<Map<String, String>, String> {

    private final static ObjectMapper mapper = new ObjectMapper();

    Logger log = LoggerFactory.getLogger(JpaConverterJson.class);

    @Override
    public String convertToDatabaseColumn(Map<String, String> meta) {
        try {
            return mapper.writeValueAsString(meta);
        } catch (JsonProcessingException e) {
            log.warn("Error convert JpaConverterJson@convertToDatabaseColumn " + e.getMessage());
        }
        return null;
    }

    @SuppressWarnings("unchecked")
    @Override
    public Map<String, String> convertToEntityAttribute(String dbData) {
        if (dbData != null) {
            try {
                return mapper.readValue(dbData, Map.class);
            } catch (IOException e) {
                log.warn("Error convert JpaConverterJson@convertToEntityAttribute " + e.getMessage());
            }
        }

        return new HashMap<>();
    }

}

And call him via Annotation:

@Convert(converter = JpaConverterJson.class)
@ElementCollection(fetch = FetchType.EAGER)
    @MapKeyColumn(name = "data")
    @Column(name = "texto")
    @CollectionTable(name = "diario", joinColumns = @JoinColumn(name = "id"))
    private Map<LocalDate, String> entrada = new HashMap<>();

Links that can help: https://www.baeldung.com/jpa-attribute-converters

Browser other questions tagged

You are not signed in. Login or sign up in order to post.