当一列是派生值时,将两个表与复合键相关联

Relating two tables with composite keys when one column is a derived value

我有两个现有的高度规范化的 tables(ActivityStatus

Create table Activity (
   id Number(10,0) not null,
   description varchar2(4000) not null,
   create_date date not null
);
Create table Status (
    table_name varchar2(20) not null,
    record_id number(10,0) not null,
    status_description varchar2(4000)
);

在这种情况下,Status table 通过以下方式与 Activity table 相关:

STATUS.TABLE_NAME = 'Activity' and STATUS.RECORD_ID = ACTIVITY.ID

它也可以与许多其他 table 相关(除了 ACTIVITY):

STATUS.TABLE_NAME = 'Scores' and STATUS.RECORD_ID = SCORE.ID
STATUS.TABLE_NAME = 'Submissions' and STATUS.RECORD_ID = submission.ID
STATUS.TABLE_NAME = 'Tickets' and STATUS.RECORD_ID = TICKET.ID
STATUS.TABLE_NAME = 'Profiles' and STATUS.RECORD_ID = Profile.ID


 - STATUS TABLE -
table_name   |   record_id  |  status_decription
-----------  | -----------  |  -----------
'Activity'   |       **12** | 'Finished'
'Profiles'   |          100 | 'Completed'
'Scores'     |          200 | 'Calculated'
'Tickets'    |         1000 | 'Paid'


 - ACTIVITY TABLE -
id           |   description  
-----------  | ------------- 
10           |  blah, blah
11           |  hey there..
**12**       |  order pizza 
13           |  pick up icecream

所以在前面的例子 tables 中,有一个 activity 个人 "'Finished' ordering his pizza"

我正在尝试与 Hibernate 建立这种关系,但是我似乎无法弄清楚这两者之间的映射 类。

@Entity(name="status")
@Table(name="Status")
public class StatusDb {

    @Column(name="table_name")
    private String tableName;

    @Column(name="record_id")
    private String recordId;

    @Column(name="status_desc")
    private String description;

    // setters/getters
    // equals/hashCode
}

@Entity(name="actvity")
@Table(name="Activity")
public class ActivityDb {

    @Column(name="id")
    @Id
    private Long id;

    @Column(name="description")
    private String description;

    // setters/getters
    // equals/hashCode
}

如何关联 Status table 和 ActivityProfilesTickets、[= 之间的 @OneToOne 映射24=] tables?

我假设 ActivityDb 是关系的 'parent'。

我会按如下方式映射我的实体:

StatusDb

@Entity(name="status")
@Table(name="Status")
public class StatusDb {

    @Column(name="table_name")
    private String tableName;

    @OneToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    @JoinColumnsOrFormulas({
        @JoinColumnOrFormula(formula=@JoinFormula(value="tableName = 'Activity'"),
        @JoinColumnOrFormula(column = @JoinColumn("record_id",                   
              referencedColumnName="id"))
    })
    private ActivityDb activityDb;

    @Id
    @Column(name="record_id")
    private String recordId;

    @Column(name="status_desc")
    private String description;

    // setters/getters
    // equals/hashCode
}

ActivityDb

@Entity(name="actvity")
@Table(name="Activity")
public class ActivityDb {

    @Column(name="id")
    @Id
    private Long id;

    @Column(name="description")
    private String description;

    @OneToOne(mappedBy = "activityDb")
    private StatusDb statusDb;
}

现在,当为 ActivityDb 实体确定 ID 时,提交事务后,相关的 StatusDb 实体将自动使用该 ActivityDb 的 ID 填充 record_id。

这是对我有用的解决方案

@Entity(name="status")
@Table(name="Status")
public class StatusDb {

    @Column(name="table_name")
    private String tableName;

    @Column(name="record_id")
    private String recordId;

    @Column(name="status_desc")
    private String description;

    // setters/getters
    // equals/hashCode
}

@Entity(name="actvity")
@Table(name="Activity")
public class ActivityDb {

    @Column(name="id")
    @Id
    private Long id;

    @Column(name="description")
    private String description;

    @OneToMany
    @Where(value="table_name='Activity'")
    @JoinTable(name="STATUS", joinColumn=@JoinColumn(name="id"), 
                        reverseJoinColumn=@JoinColumn(name="record_id")
    private Set<StatusDb> status;  // Had to to make 1:M to use where clause

    // setters/getters
    // equals/hashCode
}