简体   繁体   中英

Loading data from a table in a Map as Column Name Vs Value using Hibernate

I have been using Hibernate for a while and this time I am trying to do something uncoventional here. Not even sure of its possible.

What I want to do is to load data from a Single table, where in few of this columns will have fields defined for them for rest (almost around 20 and can increase with time) all integers, I want to load them in a Map. Such that the name of the Column become the key and and the data its value.

I am using Hibernate 4.1.4 and using Annotations to map Fields with Columns.

As further clarification: Table Definition :

CREATE TABLE TempTable
(
 id SERIAL,
 revId TEXT,
 type INTEGER,
 group INTEGER,

 col_1 INTEGER,
 col_2 INTEGER,
 col_3 INTEGER,
 col_4 INTEGER,
 col_5 INTEGER,
 col_6 INTEGER,
 col_7 INTEGER,
 col_8 INTEGER,
 col_9 INTEGER
}

The DAO Model would look something like

@Entity
@Table(name = "TempTable")
public class StatsModel {
    private Long entryId;
    private String revId;

    private Integer type;
    private Integer group;

    private Map<String, Integer> metrics; // Map in which I want columns col_1 to col_9 as "Column Name" Vs. "Value"

    @Id
    @Column(name = "id", columnDefinition = "serial")
    @Generated(GenerationTime.INSERT)
    public Long getEntryId() {
        return entryId;
    }

    public void setEntryId(Long entryId) {
        this.entryId = entryId;
    }

    @Column(name = "tx_rev")
    public String getRevId() {
        return revId;
    }

    public void setRevId(String revId) {
        this.revId= revId;
    }

    @Column(name = "nu_type")
    public Integer getType() {
        return type;
    }

    public void setType(Integer type) {
        this.type = type;
    }

    @Column(name = "nu_group")
    public Integer getGroup() {
        return group;
    }

    public void setGroup(Integer group) {
        this.group = group;
    }
}

could use a view of the remaining columns to "pivot" the columns. Then map this view, eg a view created like this (note even the DDL for the view could be dynamically created by reading the data dictionary of your db, but that is another question!)

create or replace view TempTable_metrics as
select t.id,
       pv.name as key,
       case
          when pv.name = 'COL1' then t.col1
          when pv.name = 'COL2' then t.col2
          when pv.name = 'COL3' then t.col3
       end as value
from   temp_table t,
       (
       select 'COL1' as name from dual union all
       select 'COL2' as name from dual union all
       select 'COL3' as name from dual
       ) pv

Edited: (adding how to do the hibernate part) Forgot to mention, on the java side you need these annotations by your map:

@CollectionTable(name="TempTable_metrics", joinColumns=@JoinColumn(name="id"))
@MapKeyColumn(name="key", nullable=false)
@Column(name="value")
Map<String,Integer> metrics;

Just realized though that in order to do updates you'd need some messy "instead of" triggers in your DB (I've done this with Oracle but elsewhere YMMV).

You can load your data as a map changing your query, this is the hibernate doc example:

select 
    new map(
        max(bodyWeight) as max,
        min(bodyWeight) as min, count(*) as n 
    ) 
from Cat cat

http://docs.jboss.org/hibernate/orm/3.3/reference/en/html/queryhql.html#queryhql-select

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