我应该如何在JPA中映射这两个简单实体?

时间:2013-09-07 17:01:33

标签: java hibernate jpa mapping jpa-2.0

我现在有什么:

@Entity
public class Payment {

    @Id @GeneratedValue
    private long id;

    @Column(unique = true)
    private Date period; // Only used for year and month

    ...
}

@Entity
public class Department {

    @Id @GeneratedValue
    private long id;

    ...
}

付款实体只持有所有部门只需支付一年和一个月支付的默认付款。他们之间没有任何关系,因为所有部门都支付所有付款。

我想要实现的目标:

我想区分目前的共享付款和其他部门特定付款。因此,部门可以选择使用所有共享付款(按照目前的设计)或定义自己的付款,而不是使用任何其他付款。

公司付款应该以同样的方式继续工作,我必须确保部门付款对每个部门都是唯一的。

在OOP术语中,我认为我需要建模以下任何选项:

enter image description here

可能第一个更合适。

注意我无法更改当前识别任何实体的方式。但是,我可以在任何其他领域添加唯一性。

问题:

  1. 在JPA2中执行此操作的适当方法是什么?
  2. 付款层次结构是否可行?应如何映射以确保唯一 字段不碰撞?
  3. 有没有办法避免层次结构?

3 个答案:

答案 0 :(得分:0)

我认为这种情况确实需要一种关系:

@Entity
public class Payment {

    @Id @GeneratedValue
    private long id;

    @Column(unique = true)
    private Date period; // Only used for year and month

    @ManyToOne
    private Department department;
}

这将允许为任何部门创建任何类型的付款。至于某个部门的默认付款,我认为这不属于ORM的责任范围,应该在业务逻辑中处理。

答案 1 :(得分:0)

如果我理解正确,您需要实现每个部门的独特性。可以使用compound id。 一些要点:

  • 如果您想使用复合键(period + department_id),则必须同时设置它们,并且您的默认付款应为1常见假Department所有默认payments将属于。
  • 一般情况下,我会关注Kevin's approach。这很容易,也不容易出错。无论如何你决定。

@Entity
public class Payment implements Serializable {

    @EmbeddedId
    private Period period;
}

@Embeddable
public class Period implements Serializable {
    @ManyToOne
    private Department department;
    private Date period;
}


@Entity
public class Department implements Serializable {
    @Id@GeneratedValue
    private long id;

    @OneToMany
    private List<Payment> payments = new ArrayList<Payment>();
}

答案 2 :(得分:0)

我无法将PK保留在我的付款实体中,并且还在期间和部门维护唯一索引。在数据库方面,我正在寻找这些:

付款( ID ,期间,FK_Department)

这个表应该在Period和FK_Department中添加一个唯一的索引,它允许FK_Department中的空值(因为你可以看到复合PK在这里不是一个选项,因为我需要保持使用相同的PK结构) 。使用该表,具有空FK_Department值的所有付款将是通用/默认/公司付款,而具有非空FK_Department的付款将是特定部门已分配的付款,因此它将使用那些而不是公司付款。

由于我对JPA缺乏了解,我无法复制此架构。但是,我可以创建一个类似的功能模式。这是我到目前为止所提出的最好的结果:

enter image description here

由于明显可怕的期间重复,我可以设法为每个表创建两个唯一索引:一个用于CompanyPayment实体的Period,另一个用于DepartmentPayment实体的Period和Department对:

@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public abstract class Payment {

    @Id @GeneratedValue
    private long id;

    ...
}

@Entity
public class CompanyPayment extends Payment {

    @Column(unique = true)  
    public Date period;

    ...
}

@Entity
@Table(uniqueConstraints =
    @UniqueConstraint(columnNames = { "period", "department_id" })
)
public class DepartmentPayment extends Payment {

    public Date period;

    @ManyToOne(optional = false)
    @JoinColumn(name = "department_id")
    private Department department;

    ...
}

我现在将使用此解决方案,但我愿意接受任何其他更好的解决方案。