web-dev-qa-db-fra.com

n'a pas réussi à initialiser paresseusement une collection de rôle

Bonjour, j'ai deux cours comme celui-ci:

public class Indicator implements Serializable {
...

    @OneToMany(mappedBy = "indicator",fetch=FetchType.LAZY)
    private List<IndicatorAlternateLabel>  indicatorAlternateLabels;

    public List<IndicatorAlternateLabel> getIndicatorAlternateLabels() {
        return indicatorAlternateLabels;
    }

        public void setIndicatorAlternateLabels(List<IndicatorAlternateLabel> indicatorAlternateLabels) {
            this.indicatorAlternateLabels = indicatorAlternateLabels;
        }
...
    }

public class IndicatorAlternateLabel implements Serializable {
...
 @ManyToOne(cascade = CascadeType.REFRESH, fetch = FetchType.EAGER)
    @JoinColumn(name = "IndicatorID")
    @XmlTransient
    private Indicator indicator;
...
}

Quand je les utilise comme ça:

 public MetricTypeDetail getMetricTypeDetail(Integer metricTypeId) {
        Criteria crit = sessionFactory.getCurrentSession().createCriteria(Indicator.class, "sub")
                    .add(Restrictions.eq("number", metricTypeId))
                    .setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY).setCacheable(true);
        crit.setMaxResults(1);
        Indicator indicator=(Indicator) crit.uniqueResult();
        MetricTypeDetail metricTypeDetail=new MetricTypeDetail(indicator);
        List<IndicatorAlternateLabel> indicatorAlternateLabels = null;
        indicatorAlternateLabels=indicator.getIndicatorAlternateLabels();
        metricTypeDetail.setIndicatorAlternateLabels(indicatorAlternateLabels);
        return metricTypeDetail;
    }

Ce code renvoie une exception: N'a pas pu initialiser paresseusement une collection de rôles: com.porism.service.domain.Indicator.indicatorAlternateLabels, aucune session ni session n'a été fermée.

Une idée? Je suis très nouveau à Hibernate

26
Lince81

Des exceptions paresseuses se produisent lorsque vous extrayez un objet contenant généralement une collection chargée paresseusement et tentez d'accéder à cette collection. 

Vous pouvez éviter ce problème en 

  • accéder à la collection paresseuse dans une transaction. 
  • Initalisation de la collection en utilisant Hibernate.initialize(obj);
  • Récupérer la collection dans une autre transaction
  • Utilisez Fetch profiles pour sélectionner une exécution d’extraction paresseuse ou non différée.
  • Définissez l'extraction sur non paresseuse (ce qui n'est généralement pas recommandé)

De plus, je vous conseillerais de consulter les liens related à votre droite, où cette question a déjà été répondue à plusieurs reprises. Voir également Conception de l'application de chargement paresseux d'Hibernate .

75
Johan Sjöberg

Il est possible que vous n'alliez pas chercher l'ensemble jointif. Assurez-vous d'inclure l'ensemble dans votre HQL:

public List<Node> getAll() {
    Session session = sessionFactory.getCurrentSession();
    Query query = session.createQuery("FROM Node as n LEFT JOIN FETCH n.nodeValues LEFT JOIN FETCH n.nodeStats");
    return  query.list();
}

Où votre classe a 2 ensembles comme:

public class Node implements Serializable {

@OneToMany(fetch=FetchType.LAZY)
private Set<NodeValue> nodeValues;

@OneToMany(fetch=FetchType.LAZY)
private Set<NodeStat> nodeStats;

}
3
Phaedrus

Essayez swich fetchType de LAZY à EAGER

...
@OneToMany(fetch=FetchType.EAGER)
private Set<NodeValue> nodeValues;
...

Mais dans ce cas, votre application récupérera quand même les données de la base de données . Si cette requête est très difficile, cela peut avoir un impact sur les performances . Plus ici: https://docs.Oracle.com/javaee /6/api/javax/persistence/FetchType.html

==> 73

0
Vladimir Azarov