JPA继承多个DiscriminatorValues

时间:2009-11-20 17:35:09

标签: jpa

我正在尝试使用现有数据库的继承来实现JPA。

当前的db模型如下:

Instrument
 * InstrumentID
 * Description
 * InstrumentTypeID

InstrumentType
 * InstrumentTypeID
 * StorageClass

Option
 * InstrumentID
 * (Option specific fields)

Stock
 * InstrumentID
 * (Stock specific fields)

InstrumentType和Storage Class之间存在多对一关系。换句话说,列表选项和OTC选项都具有存储类“选项”

在JPA模型中,我有一个抽象类Instrument,其鉴别值设置为InstrumentTypeID。

问题是选项子类可以同时具有InstrumentTypeID 3和5。

在JPA中对此进行建模的最佳方法是什么?

1 个答案:

答案 0 :(得分:1)

你的问题有点令人困惑,所以我对它的解释可能不正确。

但是,我怀疑你可以通过将Option分成两个类来解决你的问题。使Option成为一个抽象类,它有两个具体的子类,ListOption和OTCOption,每个子类都有自己的鉴别器值(3或5)。这两个子类中可能没有任何不同的字段,但这可以让您使用两个InstrumentTypeID来表示选项。

问题在于,这意味着在代码结构中复制InstrumentType表中的知识,这显然不是一件好事。

如果你想让它完全由数据驱动,我认为你必须改变Option和Stock,这样它们就不是Instrument的子类。它们可能是InstrumentDetails接口的实现,每个类本身就是一个实体。 InstrumentType也是一个实体。然后,您可以为InstrumentType提供一些代码,如:

@Entity
public class InstrumentType {

    private static final Map<String, Class<? extends InstrumentDetails>> STORAGE_CLASSES = new HashMap<String, Class<? extends InstrumentDetails>>();
    static {
        STORAGE_CLASSES.put("Option", Option.class);
        STORAGE_CLASSES.put("Stock", Stock.class);
    }

    public InstrumentDetails getDetails(Instrument inst) {
        return getEntityManager().find(STORAGE_CLASSES.get(getStorageClass()), inst.getID());
    }

    // NB implementation of getEntityManager() is left as an exercise to the reader

}

并且,为方便起见,仪器本身的方法:

@Entity
public class Instrument {
    public InstrumentDetails getDetails() {
        return getInstrumentType().getDetails(this);
    }
}

在这里,我已经硬连接了从存储类字符串到详细信息类的映射,但是您可以从配置文件或注入中更加动态地获取它,以便更容易添加新的存储类。