2010-04-26 4 views
2

Ceci est potentiellement un peu complexe, donc je ferai de mon mieux pour décrire ma situation - c'est aussi mon premier article ici, donc s'il vous plaît pardonner les erreurs de formatage, etc!JPA - Puis-je créer une classe Entity, en utilisant @DiscriminatorValue, qui n'a pas sa propre table?

J'utilise JPA avec l'héritage joint et une structure de base de données qui ressemble à:

ACTION 
--------- 
ACTION_ID 
ACTION_MAPPING_ID 
ACTION_TYPE 

DELIVERY_CHANNEL_ACTION 
-------------------------- 
ACTION_ID 
CHANNEL_ID 

OVERRIDE_ADDRESS_ACTION 
-------------------------- 
ACTION_ID 
(various fields specific to this action type) 

Donc, en clair, j'ai plusieurs différents types d'action, partagent un ACTION_MAPPING, qui est référencé à partir la table ACTION 'parent'. DELIVERY_CHANNEL_ACTION et OVERRIDE_ADDRESS_ACTION possèdent tous deux des données supplémentaires supplémentaires et sont mappés sur ACTION avec un FK.

Dans le monde réel, j'ai aussi une action 'supprimer', mais elle n'a pas de données supplémentaires, donc elle n'a pas de table correspondante - tout ce dont elle a besoin est un ACTION_MAPPING, qui est stocké dans la table ACTION.

Espérons que vous êtes avec moi jusqu'à présent ...

Je crée un nouveau projet à partir de zéro, donc suis assez souple dans ce que je peux faire, mais aimerais évidemment obtenir dès le départ !

Ma mise en œuvre actuelle, qui fonctionne, a trois entités vaguement définies comme suit:

@Entity 
@Table(name="ACTION") 
@Inheritance(strategy=InheritanceType.JOINED) 
@DiscriminatorValue("SUPPRESS") 
public class Action 

@Entity 
@Table(name="DELIVERY_CHANNEL_ACTION") 
@DiscriminatorValue("DELIVERY_CHANNEL") 
public class DeliveryChannelAction extends Action 

@Entity 
@Table(name="OVERRIDE_ADDRESS_ACTION") 
@DiscriminatorValue("OVERRIDE_ADDRESS") 
public class OverrideAddressAction extends Action 

qui est - je une classe de base de béton, d'action, avec une stratégie d'héritage rejoint. DeliveryChannelAction et OverrideAddressAction étendent Action. Cependant, ce qui me semble faux, c'est que ma classe Action est la classe de base pour ces deux actions, mais qu'elle constitue également l'implémentation concrète de l'action de suppression.

Pour l'instant, cela fonctionne, mais à un moment donné, plus d'actions sont susceptibles d'être ajoutées, et il y a toutes les chances que certaines d'entre elles, comme SUPPRESS, n'aient pas de données supplémentaires. Donc, ce que je voudrais faire, dans le monde du modèle objet, est que l'action soit abstraite, et que je crée une classe SuppressAction, qui est vide, à l'exception de @DiscriminatorValue ("SUPPRESS").

J'ai essayé de faire exactement ce qui est décrit ci-dessus, donc, en changeant d'action à:

@Entity 
@Table(name="ACTION") 
@Inheritance(strategy=InheritanceType.JOINED) 
public abstract class Action 

et la création:

@DiscriminatorValue("SUPPRESS") 
public class SuppressAction extends Action 

mais pas de chance - il semble fonctionner très bien pour DeliveryChannelAction et OverrideAddressAction, mais lorsque j'essaie de créer un SuppressAction et de le conserver, j'obtiens:

java.lang.IllegalArgumentException: Object: com.mypackage.SuppressAction[actionId=null] is not a known entity type. 
    at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.registerNewObjectForPersist(UnitOfWorkImpl.java:4147) 
    at org.eclipse.persistence.internal.jpa.EntityManagerImpl.persist(EntityManagerImpl.java:368) 
    at com.mypackage.test.util.EntityTestUtil.createSuppressAction(EntityTestUtil.java:672) 
    at com.mypackage.entities.ActionTest.testCRUDAction(ActionTest.java:27) 

que je suppose est dû au fait que SuppressAction n'est pas enregistré comme une entité, mais je ne sais pas comment je peux le faire, étant donné qu'il n'a pas de table associée.

Tous les pointeurs, soit des réponses ou des conseils complets pour les choses à Google (! Je suis d'idées), les bienvenus :)

EDIT: pour corriger mon stacktrace.

Répondre

1

Je pense avoir trouvé une solution qui devrait fonctionner pour moi, mes entités ressemblent maintenant:

@Entity 
@Table(name="ACTION") 
@Inheritance(strategy=InheritanceType.JOINED) 
@DiscriminatorValue("SUPPRESS") 
public abstract class Action 

@Entity 
@Table(name="DELIVERY_CHANNEL_ACTION") 
@DiscriminatorValue("DELIVERY_CHANNEL") 
public class DeliveryChannelAction extends Action 

@Entity 
@Table(name="OVERRIDE_ADDRESS_ACTION") 
@DiscriminatorValue("OVERRIDE_ADDRESS") 
public class OverrideAddressAction extends Action 

@Entity 
@Table(name="ACTION") 
@DiscriminatorValue("SUPPRESS") 
public class SuppressAction extends Action 

Donc, en gros tout ce que je manquais faisait référence à la table « parent » dans ma classe de SuppressAction, que je avait follement supposé ne fonctionnerait pas. Tous mes tests passent avec ça, et ça semble fonctionner; il semble que ce sera heureux si j'ai besoin d'ajouter d'autres actions dans le futur, une copie de SuppressAction, avec un @DiscriminatorValue différent fonctionne comme prévu, donc je pense que je suis heureux.

1

Vous pouvez, avec InheritanceType.SINGLE_TABLE

Il y a plusieurs façons d'avoir plusieurs types d'héritage pour différentes branches. See this question.

+0

Merci - cela peut être une option, mais je veux vraiment le garder comme InheritanceType.JOINED, si possible; le nombre d'actions peut devenir assez important, et chacune peut avoir plusieurs champs spécifiques, alors j'essaye d'éviter un seul monstre d'une table! – DaveyDaveDave

+0

@DaveyDaveDave alors vous avez besoin de types d'héritage mixtes .. vérifiez ma mise à jour. – Bozho

+0

Merci Bozho, on dirait que ça a peut-être fait ce que je cherchais, mais j'ai trouvé une option plus simple qui semble avoir fonctionné pour moi, donc je m'en tiendrai là, mais je garderai la tienne à l'esprit si la mienne prouve ne pas travailler plus tard. Si cela ne vous dérange pas de lire ma solution ci-dessus, et de me faire savoir s'il y a quelque chose de stupide, ce serait génial! Merci! – DaveyDaveDave

Questions connexes