简体   繁体   中英

Map<String, String> with JPA

I have JPA entity like this:

@Entity
@Table(name = "ATTRIBUTE")
public class Attribute {

    //ID stuff

    @Column(name = "NAME", nullable = false)
    private String name;

    @Column(name = "VALUE", nullable = false)
    private String value;

    //getters and setters
}

And the other entity:

@Entity
@Table(name = "ATTRIBUTE_GROUP")
public class AttributeGroup {

    //ID stuff

    @ElementCollection(fetch = FetchType.LAZY, targetClass = java.lang.String.class)
    @CollectionTable(name = "ATTRIBUTE")
    @MapKeyColumn(name = "NAME")
    @Column(name = "VALUE")
    private Map<String, String> attributes = new HashMap<>();

    public void createAttribute(String name, String value) {
        Attribute attribute = new Attribute();
        attribute.setName(name);
        attribute.setValue(value);
        attribute.setAttributeGroup(this);
        attributes.put(name, value);
    }

    public Map<String, String> getAttributes() {
        return attributes;
    }
}

I need to have a map in AttributeGroup entity which will have Attribute 's name as a key and Attribute 's value as a value.

The current approach does not work for me. When I am trying to persist records to the database it generates exception that transaction is marked as roolback only. I don't know if it is even the write way to do this, well if it is not working obviously it is not.

How can I achieve this in JPA to have a map in AttributeGroup made from Attribute name/value paired object?

I am using Hibernate via EntityManager.

You cannot have an element collection being stored in the same table as another entity, since the name/value pair cannot both be an element and an entity. Elements do not have identity, and will not have any of the other fields maintained.

What you might do instead is have a 1:M or M:M to Attribute that uses the name as the map key. You can then expose the map with name/Attribute pairs to the application directly, or create additional accessors that convert the map to a Map if required. Because of identity though, it might be a better idea to expose and use Attributes directly.

If this is not desirable, then using a String/String pairing is possible through an element collection, but you will not be able to reuse the same table as an entity or in other element collection mappings. The table will need a foreign key back to the AttributeGroup as well as fields for the name/value pairs, which will cause problems if reused.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM