动态JPA @JoinColumn名称

时间:2015-10-12 02:05:40

标签: java jpa

我对JPA不是很有经验,如果可能的话,我很好奇。

说我有一个课程Project如下:

@Entity
public class Project {

    @Id
    private String projectCode;

    private String departmentId;

    /*
     * Is something like this possible with JPA?
     */
    if (departmentId == null) {
        @JoinColumn(name = "projectCode", referencedColumnName = "assignedProject")
    } else {
        @JoinColumn(name = "departmentId", referencedColumnName = "id")
    }
    @OneToMany(targetEntity = Employee.class)
    private List<Employee> contributors;

    // getters/setters

}

所以我想根据contributors的存在填充departmentId列表。

这可能与JPA有关吗?或者我是否必须指定两个List<Employee>字段,由两个变量映射,并在我的应用程序逻辑中执行适当的检查?

感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

/*
 * Is something like this possible with JPA?
 */
if (departmentId == null) {
    @JoinColumn(name = "projectCode", referencedColumnName = "assignedProject")
} else {
    @JoinColumn(name = "departmentId", referencedColumnName = "id")
}

不,这对JPA来说是不可能的,你会很高兴它不是。

您可以通过在Java中使用继承来实现您想要的功能。首先创建一个包含表格所有常用字段的abstract实体。然后,您可以创建一个具有projectCode属性的实体子类和另一个具有departmentId属性的实体子类。

在RDBMS级别,对于像我们刚刚构建的简单对象模型,可以映射单个表。在abstract实体中,您将按如下方式进行注释以实现此目的:

@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "DTYPE", discriminatorType = STRING, length = 1)
@DiscriminatorValue("?")
@Entity

public abstract class Project {
    :
    :
}

@DiscriminatorValue("P")
public class ProjectCodeProject extends Project {
    :
    :
}

请记住,RDBMS不了解继承的知识或概念。继承仅存在于Java端。在数据库中,继承由元数据表示。 “Discriminator”是一个特殊列(此处命名为“DTYPE”),它出现在数据库表中,通知JPA特定列所代表的子类。在上面,选择代码“P”来表示具有PROJECTCODE属性而不是DEPARTMENTID属性的数据库记录。

使用这样的类层次结构可以使您拥有一个表,其行可以具有departmentId或projectCode作为属性(而不是两者)。因为表的行都是Projects,所以在Java中开发用于处理子类型的通用逻辑应该是相对简单的。