合成专栏上的JPA OneToMany

时间:2016-02-23 11:53:23

标签: java hibernate jpa

首先,这是一个遗留数据库,无法更改架构。现在想象一下我的下表:

-----------      -----------
| table A |      | table B |
-----------      -----------
| id_A    |----->| id_B    |
| col_A   |      | col_B   |
-----------      -----------

表A是主表,表B是详细信息。 id_A和id_B都是字符串BUT id_B = id_A + 4个字符。

例如,如果id_A =" 0000000123"然后有多个id_B,如下面的" 00000001230001"," 00000001230002"," 00000001230003",...是的,我知道,那应该是另一个专栏。正如我所说,这是一个遗留数据库,我就是这样找到的。

我使用的是Spring Data JPA,JPA2和Hibernate。我需要的是定义实体:

@Entity
@Table(name="A")
public class A {

    @Column(name = "id_A", length = 10, unique = true, nullable = false)
    private String idA;

    @Column(name = "col_A")
    private String colA;

    @OneToMany <-- WHAT MORE GOES HERE TO REFERENCE JUST THE SUBSTRING OF THE DETAIL id_B?
    private List<B> detail;
}

@Entity
@Table(name="B")
public class B {

    @Column(name = "id_B", length = 14, unique = true, nullable = false)
    private String idB;

    @Column(name = "col_B")
    private String colB;
}

我不知道如何引用我需要的是substr(id_b,1,10)= id_A

我该怎么做?

1 个答案:

答案 0 :(得分:1)

我能看到的唯一解决方案是在数据库级别创建一个视图。如果满足某些条件,MySQL支持可更新的视图,我们应该可以阅读和写作。

http://dev.mysql.com/doc/refman/5.7/en/view-updatability.html

(MySQL的最新版本也支持生成列,可以替代视图(http://mysqlserverteam.com/generated-columns-in-mysql-5-7-5/

创建视图:

create view VW_TABLE_B
as
select *,
substring(..) as a_id
from B

实体B映射到视图:

@Entity
@Table(name="VW_TABLE_B")
public class B {

    @Id
    @Column(name = "id_B", length = 14)
    private String id;

    @Column(name = "col_B")
    private String colB;

    protected void setId(String id){
        this.id = id;
   }
}

从JPA的角度来看,如果我们使用视图,具体表格或其他什么并不重要。然后,实体A与实体B之间的关系可以成为标准映射,其中连接列指向视图中的派生值。

@Entity
@Table(name="A")
public class A {

    @Id
    @Column(name = "id_A", length = 10)
    private String id;

    @Column(name = "col_A")
    private String colA;

    @OneToMany 
    @JoinColumn(name = "a_id")
    private List<B> detail;

    public void addB(B b){
        b.setId(this.id + new DecimalFormmat("0000").format(detail.size() + 1);
        detail.add(b);
    )
}