2010-05-27 5 views
2

Je suis nouveau à JPA et en utilisant la persistance en Java de toute façon et j'ai deux questions que je ne peux pas travailler tout à fait: je l'ai généré des tags comme:Utilisation de Java constructeurs dans des entités persistantes

@JoinColumn(name = "UserName", referencedColumnName = "UserName") 
@ManyToOne(optional = false) 
private User userName; 
@JoinColumn(name = "DatasetNo", referencedColumnName = "DatasetNo") 
@ManyToOne(optional = false) 
private Dataset datasetNo; 

Mais l'un des constructeurs de la classe, aucune référence n'est faite aux colonnes UserName ou DatasetNo alors que toutes les autres colonnes de la classe sont référencées dans le constructeur.

Quelqu'un peut-il me dire pourquoi? Les deux colonnes UserName et DatasetNo sont des «clés étrangères» sur l'entité Visualization qui correspond à une table de base de données du même nom. Je ne peux pas vraiment travailler sur l'ORM.

Et lors de l'utilisation des classes d'entités ou POJO, est-il préférable d'avoir des variables de classe comme:

privé userName utilisateur;

Lorsqu'une instance d'une classe est spécifiée ou simplement la clé de cette instance de classe comme:

private String userName;

Remerciements

Mr Morgan.

Répondre

2

La façon dont le constructeur a été écrit n'est qu'une caractéristique de l'outil de génération automatique que vous avez utilisé pour créer vos classes à partir du schéma. Si vous voulez un constructeur qui les prend, n'hésitez pas à l'ajouter. Aurait besoin de savoir lequel vous avez utilisé et comment il a été configuré pour commenter sur pourquoi cela a fonctionné de cette façon :)

Il est normalement préférable de faire correspondre les relations d'objet réelles. C'est tout le point de ORM après tout, non? Avoir un domaine d'objets réel et utilisable qui correspond à ce qui est dans la base de données, plutôt que des structures muettes qui nécessitent une manipulation supplémentaire pour être transformées en objets métier utilisables. Vous en aurez également besoin si vous voulez être capable d'écrire des requêtes d'objets de manière sensée.

Il est beaucoup plus agréable d'écrire:

Select roles from UserRoles roles where role.user.isAdmin = true 

que

Select roles from UserRules roles join Users u on roles.userName = u.userName where u.isAdmin = true 

Selon votre technologie d'affichage, il peut également être utile pour une vue contraignante d'avoir des relations de l'objet réel.

Notez que les noms de propriété créés par votre outil de génération automatique sont également arbitraires. Il n'y a aucune exigence qu'ils correspondent aux noms de colonnes.

public User getUserName() est en fait plutôt stupide.
Vous pouvez certainement changer à public User getUser()

+0

Merci pour les réponses. Je suis heureux de laisser les références d'objet en place, c'est-à-dire un ensemble de données Dataset privé; Mais j'utiliserai probablement les POJO plutôt que les tags JPA, même si cela signifie que je dois écrire moi-même une partie de l'ORM - j'ai déjà eu de la malchance avec JPA auparavant. C'est un petit système de quelque 20 tables de base dans tout ce que l'écriture manuscrite ORM utilisant des instructions préparées ne sera pas une tâche si onéreuse. D'autres tables système seront créées dynamiquement avec un nombre variable d'attributs, de sorte que l'utilisation de JPA pour celles-ci ne sera pas possible de toute façon. –

1

Tout d'abord, selon les spécifications, une entité doit avoir un constructeur sans arg public ou protégé. Il peut avoir autres constructeurs mais JPA ne s'en soucie pas, alors n'hésitez pas à ajouter ce que vous voulez/besoin tant que vous fournissez un constructeur sans arg. Deuxièmement, lorsque vous travaillez avec un ORM, vous devez "oublier les colonnes et les clés étrangères" et penser aux objets et aux associations, l'ORM prendra soin des clés étrangères et des jointures pour vous.

donc j'attendre vraiment voir quelque chose comme ceci:

@JoinColumn(name = "UserName", referencedColumnName = "UserName") 
@ManyToOne(optional = false) 
private User user; 
@JoinColumn(name = "DatasetNo", referencedColumnName = "DatasetNo") 
@ManyToOne(optional = false) 
private Dataset dataset; 

La différence est subtile (erf, techniquement il n'y a pas de différence), mais fondamentale dans ce qu'elle communique: les attributs de vos entités ne sont pas les clés étrangères mais instances d'autres entités (d'où l'objet de réflexion et les associations).

La même chose s'applique lors de l'écriture de requêtes en utilisant JPQL. Vous devez penser à l'objet et naviguer dans les associations. Par exemple, pour récupérer dans l'JPQL userName d'un User pour une donnée ... eh bien, nous allons appeler Foo l'entité tenue User et Dataset ici:

select f.user.userName from Foo f where f.id = :id 
Questions connexes