Your question is a bit confusing, so my interpretation of it may be incorrect.
However, i suspect that you can solve your problem by splitting Option into two classes. Make Option an abstract class with two concrete subclasses, ListOption and OTCOption, each of which has its own discriminator value (3 or 5). There may not be any different fields in the two subclasses, but this will let you use both InstrumentTypeIDs to mean Option.
The problem is that this means duplicating the knowledge that is in your InstrumentType table in the structure of your code, which is obviously not a good thing.
If you want to make it entirely data-driven, i think you will have to change Option and Stock so that they are not subclasses of Instrument. They could perhaps be implementations of an InstrumentDetails interface, and each class would be an entity in its own right. The InstrumentType would also be an entity. You could then give the InstrumentType some code like:
@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
}
And, for convenience, a method on the Instrument itself:
@Entity
public class Instrument {
public InstrumentDetails getDetails() {
return getInstrumentType().getDetails(this);
}
}
Here, i've hardwired the mapping from storage class strings to details classes, but you could get it more dynamically, from a configuration file or by injection, to perhaps make it easier to add new storage classes.