2017-04-24 1 views
1

J'ai un problème pour obtenir l'objet que je veux sans toutes les associations d'enfants.
j'ai mon site classe
La charge paresseuse ne fonctionne pas - J'ai seulement besoin de l'objet parent, pas de toutes les associations

 

    @Entity 
    @Table(name = "Sites") 
    public class Site { 


    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    @Column(name = "Id_Site", unique = true, nullable = false) 
    private long Id_Site; 
    private String ...; 
    private boolean ...; 
    private long ...; 
    private Date ...; 
    private Date ...; 
    private String ...; 

    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY) 
    private Set sequences = new HashSet(); 

    @ManyToOne 
    private ... ...; 

    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY) 
    private Set ... = new HashSet(); 

    @ManyToOne 
    private ... ...; 

    public constructor... 

    public set.. 
    public get.. 

donc, je ne ai besoin objet du site sans séquences Association
dans ma table de séquence je

 



    @Entity 
    @Table(name = "Sequences") 
    public class Sequence { 

    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    @Column(name = "Id_Sequence", unique = true, nullable = false) 
    private long Id_Sequence; 
    private Date ....; 
    private Date ....; 
    private String ....; 
    private String ....; 
    private String ....; 
    private int ....; 
    private int ....; 
    private double ....; 
    private double ....; 
    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER) 
    private Set traceSequences = new HashSet(); 
    @ManyToOne(cascade = CascadeType.ALL) 
    private Site site; 

    public constructor... 

    public set.. 
    public get.. 



donc, quand j'utiliser FetchType.LAZY et appeler ma méthode:

 

    @Override 
     public Site findSiteByName(String Name_Site) { 
      List sites = entityManager.createQuery("SELECT s FROM Site s").getResultList(); 
      for (Site item : sites) { 
       if (item.getNom_Site().equals(Name_Site)) { 
        return item; 
       } 
      } 

      return null; 
     }

Je reçois cette erreur:

n'a pas réussi à initialiser paresseusement une collection de rôle: xxx.xxx.xxx. xxx.xxx.site.Site.sequences, n'a pas pu initialiser proxy - aucune session

et quand je l'utilise FetchType.EAGER, je reçois l'objet du site, mais je reçois aussi tous les objets séquences, et tous les objets d'associations autres (C'est normal, je sais)

S'il vous plaît, quelqu'un sait pourquoi l'annotation paresseux ne fonctionne pas, et comment résoudre ce problème

+0

Vous malentendu. Lazy Loading ** fonctionne **: c'est pourquoi vous obtenez l'erreur. Un code plus récent essaie alors d'accéder à l'association paresseuse (un Serializer JSON par exemple) et il ne peut pas être chargé car il n'y a pas de session. –

Répondre

2

Ces erreurs paresseux se produit lorsque le JPA tente d'obtenir les données après la session est fermée.

Mais utiliser impatiemment influencera toutes les requêtes qui incluent cette entité. Essayez d'utiliser une recherche de jointure dans la requête au lieu de l'avide.

+0

Oui, je suis d'accord avec vous. Mais, la recherche de jointure dans la requête au lieu de l'influence enthousiaste aussi toutes les requêtes, juste même comme en utilisant seulement le Eager. – Adams

0

Quelque part dans votre code vous appelez Site.GetSequences(), peut-être itératif dans la vue ou dans une autre partie de votre code. Il ne semble pas que le morceau de code que vous avez généré génère l'exception.

Si vous essayez d'utiliser une collection qui n'est pas chargée dans votre entité, le code renvoie l'exception que vous avez mentionnée.

Pour résoudre ce problème, identifier où vous utilisez le sequences et les charger avant d'utiliser en changeant la fetch pour EAGER ou en utilisant la join fetch dans votre requête.

+0

Merci de votre aide, je commente toutes les GetSequences qui peuvent l'appeler. Mais, ma question est la suivante: si j'utilise Join Fetch, j'obtiendrai tous les éléments de Sequences, (même chose que d'utiliser impatiemment), et je n'ai pas besoin de séquences. J'ai juste besoin de l'objet site sans avoir toutes les dépendances. – Adams

0

Le renvoi d'une entité gérée en veille prolongée (ou d'une collection d'entités gérées en mode hibernate) provoquera vraisemblablement ce genre de problèmes à moins que vous soyez très prudent sur ce qui est retourné et ce qui était hiberné lorsque la session était disponible. Je dirais créer un DTO (ou une collection de DTO) et peupler ses champs comme vous le souhaitez. Il existe de nombreux cadres de conversion Entité à DTO; mon fav est ModelMapper.J'ai également tendance à être d'accord avec d'autres suggestions pour jouer avec FetchType mais depuis que les DTO sont peuplées par nous, nous savons ce que nous avons peuplé par opposition aux relations d'entités qui sont peuplées par hibernate basé sur des annotations.

Si vous avez besoin de quelque chose dans le DTO vous demandez simplement à l'entité et puisque la session serait disponible à ce moment-là, vous pouvez remplir n'importe quel champ que vous pensez avoir besoin de l'interface utilisateur.

Je ne veux pas détourner ce sujet vers DTO et Entity mais c'est comme ça que je le ferais.

Cela peut être utile aussi Avoid Jackson serialization on non fetched lazy objects