Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/389.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用JPA继承作为获得不同方法实现的一种方式有意义吗?_Java_Jpa - Fatal编程技术网

Java 使用JPA继承作为获得不同方法实现的一种方式有意义吗?

Java 使用JPA继承作为获得不同方法实现的一种方式有意义吗?,java,jpa,Java,Jpa,所以,我一直在努力熟悉JPA的继承特性,到目前为止我真的很喜欢它们。我最近想到的一件事是,它们实际上可以用于除检索数据之外的其他用途。考虑到它可以基于鉴别器值获得子类,继承实际上是一种将配置字段转换为实现的方便方法。在我的知识与经验之比处于“刚好足够危险/不足以始终意识到这一点”的阶段,我想最好问问这是不是一个好主意 以PRODUCT and BILLTYPE表为例 Product: int Id int billtypeid Billtype: int id varchar[15] desc

所以,我一直在努力熟悉JPA的继承特性,到目前为止我真的很喜欢它们。我最近想到的一件事是,它们实际上可以用于除检索数据之外的其他用途。考虑到它可以基于鉴别器值获得子类,继承实际上是一种将配置字段转换为实现的方便方法。在我的知识与经验之比处于“刚好足够危险/不足以始终意识到这一点”的阶段,我想最好问问这是不是一个好主意

以PRODUCT and BILLTYPE表为例

Product:
int Id
int billtypeid

Billtype:
int id
varchar[15] description
Billtype只是产品的一种计费策略(我们会说一些订单可能按重量计费,而其他订单可能只按案例计费)。在开票过程中,每种票据类型都需要使用不同的方法。Billtype表可能只有少数条目,并且不应该增长到非常大

使用继承对抽象Billtype实体进行子类化是否有意义?抽象Billtype实体还为发票代码所需的不同方法定义了接口?大概是这样的:

@Entity
@DiscriminatorColumn("description")
public abstract class BillType {
   // Getters, setters
   // Abstract methods that could be used elsewhere - ex:
   // BigDecimal calculateInvVal(...)
}


@Entity
@DiscriminatorValue("by case")
public class CaseBillType extends BillType {
   // Implementation of calculateInvVal - now when invoicing code needs this method, 
   // the right one is always associated with the current product!
}
这提供了一种方便的方法,可以将行为与数据库中表示配置数据的字段相关联,但会将业务代码与实体相混合(大多数人认为,这是非常顽皮的)。可能会有一种设计模式来解决我的剧目中缺少的这个问题,但我真的希望避免编写大量“如果bill类型是this,那么获取这个子类,如果bill类型是this,等等”代码


我从答案中寻找的是对这种技术的潜在缺陷的解释,我可能看不到这种解释有助于寻找解决此问题的另一种解决方案。

如果可以添加,在运行时删除和修改票据类型,而无需重建和重新部署应用程序的新版本。你的例子并非如此

因此,如果您有一组静态的票据类型,每个类型都定义了一个由BillType子类封装的静态行为,那么您只需使用BillType枚举即可。此枚举的每个实例定义自己的行为。您不需要实体层次结构和额外的表

用于计算产品实体中的无效值的代码将完全相同:

BigDecimal computeInVal() {
    billType.calculateInVal(this);
}
获取所有账单类型的代码为

return BillType.values();
并将票据类型与产品关联,而不是使用以下代码:

product.setBillType(em.find(BillType.class, ID_OF_CASE_BILL_TYPE));
你只需要

product.setBillType(BillType.BY_CASE);