简体   繁体   中英

Persist a Map< Long, Boolean > with JPA/Hibernate?

I am not an expert in JPA/Hibernate and I really do not know if what I am trying to achieve is not possible or I am doing it wrong and since I expect that is the latter here goes nothing.

I have a Map< Long, Boolean > which I am trying to persist into a table and was following the example described here: Storing a Map<String,String> using JPA

And other examples which basically describe the same practice.

What I was trying to do is:

@Id    
private Long id;

@ElementCollection
@CollectionTable(name = "state_map", joinColumns = @JoinColumn(name = "id"))
@MapKeyColumn(name = "name")
@Column(name = "value")
@Type(type = "org.hibernate.type.TrueFalseType")
private Map<Long, Boolean> myBooleanMap;

And my table is defined as:

CREATE TABLE if not exists state_map
(id BIGINT NOT NULL,
name BIGINT NOT NULL,
value CHAR);

But then I get a HibernateException: Wrong column type in STATE_MAP for column value. Found: bigint, expected: char(255)

When I change the bigint to char(255) the entityManager starts but when I am trying to put in the map and persist I am getting a java.lang.ClassCastException: java.lang.Long cannot be cast to java.lang.Boolean. I suppose that the @Type annotation is applied on the key column instead on the value column.

The only way I managed to make it work is with Map< String, String >. Also I have tried to do everything in the same table which did not work so I have to declare another with just the surrogate id which is mapped to the entity:

CREATE TABLE if not exists state_id
(id serial primary key);

@Entity
@Table(name = "state_id")
public class StateModel {...}

Hope somebody can help, thanks.

UPDATE - SOLUTION

I have solved by introducing an embeddable to wrap the boolean value column:

@Embeddable
class BooleanWrapper{

     @Column(name = "value")
     @Type(type = "org.hibernate.type.TrueFalseType")
     private Boolean myBoolean;}

And my map became:

@ElementCollection
@CollectionTable(name = "state_map", joinColumns = @JoinColumn(name = "id"))
@MapKeyColumn(name = "name")
private Map<Long, BooleanWrapper> myBooleanMap;

I see you have annotated myBooleanMap with @Type(type = "org.hibernate.type.TrueFalseType") which I think is incorrect. You can define TrueFalseType for a CHAR column not for map. I don't think bigint is a problem

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