Relations JPA OneToMany et ManyToOne

J’ai trois classes dont le nom est Utilisateur et cet utilisateur a d’autres instances de classes. Comme ça;

public class User{ @OneToMany(fetch=FetchType.LAZY, cascade = CascadeType.ALL) public List aPosts; @OneToMany(fetch=FetchType.LAZY, cascade = CascadeType.ALL) public List bPosts; } public class BPost extends Post { @ManyToOne(fetch=FetchType.LAZY) public User user; } public class APost extends Post { @ManyToOne(fetch=FetchType.LAZY) public User user; } 

Cela fonctionne comme ça mais génère des tables emty dans la firebase database. Qui doit contenir des clés étrangères. Lorsque j’ai essayé d’utiliser mappedBy et JoinColumn annotains, j’ai échoué. Comment puis-je résoudre ça?

Informations supplémentaires:

Quand j’ai changé avec;

  @ManyToOne(fetch=FetchType.LAZY) @JoinColumn(name="id") public User user; 

et

  @OneToMany(fetch=FetchType.LAZY, cascade = CascadeType.ALL, mappedBy="id") public List aPosts; 

Je suis en train

Une erreur JPA s’est produite (impossible de générer EntityManagerFactory): colonne répétée dans le mappage de l’entité: models.post.APost column: id (doit être mappé avec insert = “false” update = “false”)

Final Edit: Finalement, je me suis complètement trompé à propos des annotations jpa. 🙁 Quand je change

 @OneToMany(fetch=FetchType.LAZY, cascade = CascadeType.ALL, mappedBy="id") 

à

 @OneToMany(fetch=FetchType.LAZY, cascade = CascadeType.ALL, mappedBy="user") 

et

 @ManyToOne(fetch=FetchType.LAZY) @JoinColumn(name="user_id") 

Tout fonctionne bien. 🙂

Comme je l’ai expliqué dans cet article et dans mon livre, Persistance Java hautes performances , vous ne devez jamais utiliser l’annotation unidirectionnelle @OneToMany car:

  1. Il génère des instructions SQL inefficaces
  2. Il crée une table supplémentaire qui augmente l’empreinte mémoire de vos index DB

Maintenant, dans votre premier exemple, les deux parties possèdent l’association, et c’est mauvais .

Alors que @JoinColumn laissait le côté @OneToMany responsable de l’association, ce n’est certainement pas le meilleur choix. Par conséquent, utilisez toujours l’atsortingbut @OneToMany côté @OneToMany .

 public class User{ @OneToMany(fetch=FetchType.LAZY, cascade = CascadeType.ALL, mappedBy="user") public List aPosts; @OneToMany(fetch=FetchType.LAZY, cascade = CascadeType.ALL, mappedBy="user") public List bPosts; } public class BPost extends Post { @ManyToOne(fetch=FetchType.LAZY) public User user; } public class APost extends Post { @ManyToOne(fetch=FetchType.LAZY) public User user; } 

Je ne suis pas vraiment sûr de votre question (la signification de “table vide”, etc., ou comment mappedBy et JoinColumn ne fonctionnaient pas).

Je pense que vous essayiez de créer des relations bidirectionnelles.

Tout d’abord, vous devez décider quel côté “possède” la relation. Hibernate va configurer la base de relation de ce côté. Par exemple, supposons que je fasse la relation avec le côté Post (je simplifie votre exemple, juste pour garder les choses en point), le mapping ressemblera à ceci:

(J’espère que la syntaxe est correcte. Je les écris juste en mémoire. Cependant, l’idée devrait être bonne)

 public class User{ @OneToMany(fetch=FetchType.LAZY, cascade = CascadeType.ALL, mappedBy="user") private List posts; } public class Post { @ManyToOne(fetch=FetchType.LAZY) @JoinColumn(name="user_id") private User user; } 

Ce faisant, la table pour Post aura une colonne user_id qui stockera la relation. Hibernate obtient la relation par l’ user dans Post (au lieu de publier des posts dans User . Vous remarquerez la différence si vous avez Post user Post , mais qu’il manque des posts ).

Vous avez mentionné mappedBy et JoinColumn ne fonctionne pas. Cependant, je pense que c’est en fait la bonne façon. Dites si cette approche ne fonctionne pas pour vous et donnez-nous un peu plus d’informations sur le problème. Je crois que le problème est dû à autre chose.


Modifier:

Juste un peu plus d’informations sur l’utilisation de mappedBy comme c’est généralement déroutant au début. Dans mappedBy , nous plaçons le “nom de la propriété” dans la partie opposée de la relation bidirectionnelle et non dans le nom de la colonne de la table.

Comme vous sauvegarderez directement APost et BPost, cela signifie qu’APost et BPost seront les propriétaires de la relation. Comme l’utilisateur ne possède pas la relation, il y aura un atsortingbut mappedBy dans l’annotation @OneToMany.

 public class User{ @OneToMany(fetch=FetchType.LAZY, cascade = CascadeType.ALL,mappedBy="user", targetEntity = APost.class) public List aPosts; @OneToMany(fetch=FetchType.LAZY, cascade = CascadeType.ALL,mappedBy="user", targetEntity = BPost.class) public List bPosts; } public class BPost extends Post { @ManyToOne(fetch=FetchType.LAZY) @JoinColumn(name="user_id",referencedColumnName="id") public User user; } public class APost extends Post { @ManyToOne(fetch=FetchType.LAZY) @JoinColumn(name="user_id",referencedColumnName="id") public User user; } 

L’annotation @JoinColumn sera chargée d’append la clé étrangère dans Apost et BPost.