multiple discriminator columns for persistent subclasses
I have banged my self with a very particular problem. Using OpenJPA (KODO 4.1) is there a way to use more than one column as a discriminator column?
My problem 开发者_Go百科is that i have a table structure (which i have limited ability to modify of course) similar to this:
Table VEHICLE EXPENSIVE_CAR CHEAP_CAR EXPENSIVE_BOAT CHEAP_BOAT
---------------------------------------------------------------------------------
HORSE_POWER LUXURY_ACC CLASIFICATION SIZE SIZE
MEDIUM EXTRAS TV_SIZE
IS_EXPENSIVE CLASIFICATION
Where medium would discriminate between boat and car and is expensive would discriminate bettwen expensive or cheap.
So, is there any way to achieve this with the inheritance capabilities provided by OpenJPA (i know hibernate can use discriminator formulas but i am trying not to switch from the default JPA provider).
As a bonus if you can tell me about the custom discriminator strategies from OpenJPA that would be great since i have a hunch that it could be a plausible solution (even though i would prefer a vendor independent one)
Thanks a lot
Let's start backwards.
Discriminator strategies define the type of the column that discriminates related entities in the hierarchy. In JPA 1.x, it can be either a string (this is the default), a char and an integer. Example:
import javax.persistence.DiscriminatorType;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
@Entity
@DiscriminatorColumn(name = "TYPE", discriminatorType = DiscriminatorType.STRING, length = 5)
@DiscriminatorValue("FOO")
public class Foo { ... }
@Entity
@DiscriminatorValue("BAR")
public class Bar extends Foo { ... }
@Entity
@DiscriminatorValue("BAZ")
public class Baz extends Baz { ... }
If you are using is single table inheritance strategy as the default, this setup means that all these entities that are in the hierarchy will be mapped to the database table of the parent class, meaning you'll have a FOO table in your db with all the attributes of classes Foo, Bar and Baz plus a discriminator column called TYPE with the type of string (most likely some varchar-variant, length 5) and for each entity type, the respective discriminator value will be inserted automatically when persisted.
When you are finding Bar or Baz entities with JPQL, JPA will be able to find the entities from the FOO table (because that is the parent entity's table), and by relying on the contents of the discriminator column, your JPA provider will be able to discriminate between creating some Bar or Baz entities.
If you'd set the discriminator type to INTEGER or CHAR, then you could write for the values 1, 2, 3 or "A", "B", "C" etc. respectively.
Now to the OpenJPA question.
AFAIK there's no way to easily specify multiple discriminator values with OpenJPA, but you can create some more complex entity hierarchies, so if you'd be able to modify the schema, you could create a Vehicle entity, a Car, a Boat and both an ExpensiveBoat and an ExpensiveCar.
If you have to stick with your schema, I guess (but FIXME) you are using the joined or the table per class inheritance strategy which means you cannot use the discriminator feature that JPA provides.
精彩评论