在JPA中将继承用于数据类型

时间:2012-01-06 23:06:55

标签: java design-patterns inheritance jpa orm

我有一些实体看起来像这样:

@Entity
public abstract class AbstractEntity{

    @Id
    private Long id;
    String name;
    User author;
    @Lob
    byte[] data;

}


public class EntityOne extends AbstractEntity{
    // nothing new
}


public class EntityTwo extends AbstractEntity{
    // nothing new
}


public class EntityThree extends AbstractEntity{
    // nothing new
}

超类中定义的byte[]是每个子类实体的有趣部分。我想要子类化的原因是强制执行输入规则,因为程序的某些部分需要EntityThree,而程序的某些部分需要EntityTwobyte[]将具有从子类到子类的完全不同的含义。

感觉有点奇怪,因为我不希望任何子类会添加任何字段或方法......所以我只使用继承作为打字工具。

这是一个合理的设计吗?完成此任务的更好方法是什么?它会破坏任何最佳做法吗?

2 个答案:

答案 0 :(得分:2)

这是一个很好的OO练习。对于数据库,使用SINGLE_TABLE继承策略(默认),也可以为每个子类使用自定义@DiscriminatorValue,否则您将在表中获得类名。

从DBA的角度来看,这与使用属性TYPE的单个类没有区别。

对于OO,子类可以更有用,例如您可以使用它来以不同方式实现某些方法,或者实现访问者或策略模式,而不是繁琐的if-then-else或instanceof结构。

答案 1 :(得分:0)

如果不知道确切的用例,很难说,但看起来你只想重用所有实体中的公共字段,但没有其他实体会引用AbstractEntity - 只能引用一个特定的子类。在这种情况下,您应该使用@MappedSuperclass而不是@Entity映射超类。每个实体都有自己的表,并且可以覆盖映射的超类中定义的映射。

请注意,如果我弄错了,并且您确实需要实体继承,那么使用instanceof(至少使用Hibernate)会导致问题,因为您可能拥有基类的代理,而不是知道外键指向的确切子类,因此它不是任何子类的实例。