如何用硬编码值替换@JoinColumn?

时间:2015-01-08 01:00:07

标签: java jpa

有关更多背景信息,请参阅my other question

我想将Employee实体类加入Code实体类,但代码PK是复合的(DOMAIN,CODE),因为它列出了许多不同的代码域,但是代码中的代码是class / table都来自单个域,无需在Employee类/表中拥有域字段(因为它总是相同的)。

我可以使用 Employee 表中的CODE字段和硬编码值(例如 EMP_TYPE <)将 Employee 加入 Code / em>)而不是冗余列?

如果我的 Employee 类/表确实有那个冗余列,我会像这样加入:

@JoinColumns({
        @JoinColumn(name = "EMP_TYPE_CODE", referencedColumnName = "CODE"),
        @JoinColumn(name = "DOMAIN", referencedColumnName = "DOMAIN)})
    @ManyToOne(optional = false)
    private Code sharedStatute;

但我真的不希望在DB和类中有这个额外的列,因为它总是一样的。

我想要完成的内容与SQL中的以下内容相同:

SELECT e.emp_id, e.first_name, e.last_name, c.description as emp_type
FROM Employee e JOIN Code c
ON e.emp_type_code = c.code
WHERE c.domain = 'EMP_TYPE'

而不是在Employee表中添加字段domain并使用相同的值('EMP_TYPE')填充每个单个记录然后执行:

SELECT e.emp_id, e.first_name, e.last_name, c.description as emp_type
FROM Employee e JOIN Code c
ON e.emp_type_code = c.code
AND e.domain = c.domain

前者效率更高,因为它使我不必拥有冗余字段。所以我想做的是同样的事情,但在JPA

你们中的一些人可能会说“为什么不为每个代码都有一个单独的查找表”,但我认为这是一个糟糕的想法,会导致数据库表和相应的应用程序实体混乱。使代码类型(或域)分区的单个代码查找表要好得多。

2 个答案:

答案 0 :(得分:3)

这应该有用吗?

@JoinColumn(name = "EMP_TYPE_CODE", referencedColumnName = "CODE")
@Where(clause = "domain = 'EMP_TYPE'")
@ManyToOne(optional = false)
private Code sharedStatute;

答案 1 :(得分:0)

注意:显然此解决方案仅限OpenJPA。

有一种方法可以只使用javax.persistence注释:

@JoinColumns({
    @JoinColumn(name = "EMP_TYPE_CODE", referencedColumnName = "CODE"),
    @JoinColumn(name = "CODE_TABLE_NAME.DOMAIN", referencedColumnName = "'EMP_TYPE'")})
@ManyToOne(optional = false)
private Code sharedStatute;

请注意referencedColumnName中的单个引号,这是您要查找的字符串值。

但是有一个缺点,当您的实体中有多个Code对象时,DOMAIN上的连接只会在jpa中完成一次,从而产生错误的结果。目前,我通过懒散地使这些场负荷来规避这一点,但这并不理想。

更多信息here