Java 当一列是派生值时,使用复合键关联两个表
我有两个现有的高度规范化的表(Java 当一列是派生值时,使用复合键关联两个表,java,hibernate,jpa,one-to-one,Java,Hibernate,Jpa,One To One,我有两个现有的高度规范化的表(Activity和Status) 在这种情况下,状态表通过以下方式与活动表相关: STATUS.TABLE_NAME = 'Activity' and STATUS.RECORD_ID = ACTIVITY.ID 它还可以与许多其他表相关(活动除外): 因此,在前面的示例表中,有一个活动,其中一个人“‘完成’订购他的比萨饼” 我试图与Hibernate建立这种关系,但是我似乎无法弄清楚这两个类之间的映射 @Entity(name="status") @Table(
Activity
和Status
)
在这种情况下,状态
表通过以下方式与活动
表相关:
STATUS.TABLE_NAME = 'Activity' and STATUS.RECORD_ID = ACTIVITY.ID
它还可以与许多其他表相关(活动除外):
因此,在前面的示例表中,有一个活动,其中一个人“‘完成’订购他的比萨饼”
我试图与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
}
如何关联
@OneToOne
状态表和活动表、配置文件、票证、工作流表之间的映射?我假设ActivityDb是关系的“父级”
我将映射我的实体,如下所示:
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
}
@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;
}
活动数据库
@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
}
@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填充记录id。我假设ActivityDb是关系的“父项”
我将映射我的实体,如下所示:
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
}
@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;
}
活动数据库
@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
}
@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填充记录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
}
@实体(name=“status”)
@表(name=“Status”)
公共类状态数据库{
@列(name=“table_name”)
私有字符串表名;
@列(name=“record\u id”)
私有字符串记录ID;
@列(name=“status\u desc”)
私有字符串描述;
//二传手
//等于/哈希代码
}
@实体(名称=“活动”)
@表(name=“活动”)
公共类活动数据库{
@列(name=“id”)
@身份证
私人长id;
@列(name=“description”)
私有字符串描述;
@独身癖
@其中(value=“table_name='Activity'”)
@JoinTable(name=“STATUS”,joinColumn=@joinColumn(name=“id”),
reverseJoinColumn=@JoinColumn(name=“record\u id”)
private Set status;//必须设置1:M才能使用where子句
//二传手
//等于/哈希代码
}
以下是对我有效的解决方案
@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
}
@实体(name=“status”)
@表(name=“Status”)
公共类状态数据库{
@列(name=“table_name”)
私有字符串表名;
@列(name=“record\u id”)
私有字符串记录ID;
@列(name=“status\u desc”)
私有字符串描述;
//二传手
//等于/哈希代码
}
@实体(名称=“活动”)
@表(name=“活动”)
公共类活动数据库{
@列(name=“id”)
@身份证
私人长id;
@列(name=“description”)
私有字符串描述;
@独身癖
@其中(value=“table_name='Activity'”)
@JoinTable(name=“STATUS”,joinColumn=@joinColumn(name=“id”),
reverseJoinColumn=@JoinColumn(name=“record\u id”)
private Set status;//必须设置1:M才能使用where子句
//二传手
//等于/哈希代码
}
谢谢您的帮助!我看到的唯一问题是,StatusDb
除了与ActivityDb
相关外,还可以/确实与许多其他表/实体相关。有没有办法避免将所有与之相关的实体都放在类中?不确定您的意图是什么,但您不需要将所有列映射到对于一个表,您可以选择您想要的。此外,如果您担心在加载StatusDb期间会获取这些其他依赖项,请使用FetchType标记它们。LAZYMy的目的是根据它们的表名和记录id将StatusDb
实体与许多其他实体关联。在您的示例中,您特别关联了<代码>状态数据库
到活动数据库
,方法是放置“活动数据库”的引用在StatusDb
表中。虽然这可能适用于给定的示例,但我正尝试允许它适用于活动之外的其他关系。我更新了我的初始问题,提供了我们可能看到的关系的进一步示例。好的,我现在明白了。使用JoinColumnFormula查看我更新的答案我不认为这对扩展的问题有效。在StatusDb
实体中仍然有一个ActivityDb
实体。因此,如果我想在我的'ProfileDb'实体和StatusDb
实体之间创建一个关系,那么我必须嵌入一个ProfileDb实例……有没有办法使关系更通用?谢谢感谢您的帮助!我看到的唯一问题是,StatusDb
除了与ActivityDb
相关外,还可以/确实与许多其他表/实体相关。有没有办法避免将所有与之相关的实体都放在类中?不确定您的意图是什么,但您不需要映射表的所有列,y您可以选择您想要的。此外,如果您担心在加载StatusDb期间会获取这些其他依赖项,请使用FetchType标记它们。LAZYMy的目的是根据它们的表名和记录id将StatusDb
实体与许多其他实体关联。在您的示例中,您特别关联了StatusDb
至活动数据库
,方法是将“活动数据库”作为参考在StatusDb
表中。虽然这可能适用于给定的示例,但我正尝试允许它适用于活动之外的其他关系。我更新了我的初始问题,提供了我们可能看到的关系的进一步示例。好的,我现在明白了。使用JoinColumnFormula查看我更新的答案我不认为这对扩展的问题有效。仍然有一个ActivityDb
entit