2012-07-06 1 views
0

Bonjour J'ai créé plusieurs relations en hibernation. Voici le code pour cela.TROUVEZ LA MÉMOIRE en hibernation

il y a des milliers d'enregistrements présents dans la table B qui est un lien vers un enregistrement unique de la table A. Lorsque j'ai utilisé la méthode getBList(), elle retournera des milliers d'enregistrements et JAVA sortira de mémoire. Alors, comment puis-je résoudre ce problème.

@Entity 
@Table(name = "A") 
public class A { 

    private int Id; 
    private String aName; 
    private List<MksReleaseInfo> bList; 

    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    @Column(name = "id") 
    public int getId() { 
     return releaseId; 
    } 

    public void setId(final int Id) { 
     this.Id = Id; 
    } 

    @Column(name = "aname", unique = true) 
    public String getAName() { 
     return aName; 
    } 

    public void setAName(final String aName) { 
     this.aName = aName; 
    } 
    @OneToMany(mappedBy = "aName") 
    public List<MksReleaseInfo> getBList() { 
     return bList; 
    } 

    public void setBList(final List<B> bList) { 
     this.bList = bList; 
    } 
} 


@Entity 
@Table(name = "B") 
public class B { 

    private int bIndex; 
    private int bpriority; 
    private A aName; 

    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    @Column(name = "id") 
    protected int getBIndex() { 
     return mksReleaseInfoIndex; 
    } 

    protected void setBIndex(final int bIndex) { 
     this.bIndex = bIndex; 
    } 

    @Column(name = "priority") 
    public int getBPriority() { 
     return bpriority; 
    } 

    public void setBPriority(final int bpriority) { 
     this.bpriority = bpriority; 
    } 

    @ManyToOne 
    @JoinColumn(name = "Id") 
    public A getAName() { 
     return aName; 
    } 

    public void setAName(final A aName) { 
     this.aName = aName; 
    } 
} 

après tous les commentaires j'ai implémenté le code suivant. mais encore une fois il donne de mémoire. Dois-je vider la mémoire explicitement et comment?

public List<B> getList(String name, int offset, int limit) throws DAOException { 
     try { 
      String hql = "from B where name = :name"; 
      begin(); 
      Query query = getSession().createQuery(hql); 
      query.setString("name", name); 

      if(offset > 0){ 
       query.setFirstResult(offset); 
      } 

      if(limit > 0){ 
       query.setMaxResults(limit); 
       query.setFetchSize(limit); 
      } 
      commit(); 
      return query.list(); 
     } catch (HibernateException e) { 
      rollback(); 
     } 
    } 

    public Long countB(String name) throws DAOException { 
     try { 
      String hql = "select count(*) from B where name = :name"; 
      begin(); 
      Query query = getSession().createQuery(hql); 
      query.setString("name", name); 
      commit(); 
      return (Long)query.uniqueResult(); 
     } catch (HibernateException e) { 
      rollback(); 
     } 
    } 


    long count = countB(name); 
    int counter = (int) (count/200); 
    if(count%200 > 0){ 
     counter++; 
    } 
    for(int j = 0;j<counter;j++){ 
     lists = getList(name, j*200, 200); 

     for(B count1 : lists){ 
      System.out.println(count1); 
     } 
    } 
+0

Donc, vous avez dit quel est le problème, je vous recommande de changer votre algorithme. Qu'est-ce que tu veux faire? Je crois qu'il y a de très rares cas où vous avez besoin d'aller chercher des milliers de "plusieurs" côtés de la relation ensemble. –

+0

Vous pouvez tester 'StatelessSession' aussi, il peut aider .... –

Répondre

1

Vous pouvez introduire un DAO afin de récupérer les enregistrements de B donné un objet A d'une manière paginée.

Par exemple:

public interface BDao { 

    Page findByA(A a, PageRequest pageRequest); 

} 

Peut-être que vous pourriez prendre une idée de l'approche taked dans Spring Data

1

Set MaxResults propriété de source de données, il établira limite sur le nombre d'enregistrements que vous obtenez.

En outre, vous pouvez augmenter la taille de la mémoire de segment Java en utilisant -Xmx256m. Cela définira la taille maximale d'allocation de tas à 256 Mo. Vous pouvez le définir selon vos besoins.

+0

nous pouvons définir la propriété MaxResults dans l'objet de requête. mais j'utilise simplement la méthode getBList(). Alors, comment vais-je avoir le contrôle de cette fonction. Et la chose est que je veux tout le dossier d'enregistrement particulier dans A, mais pas immidiately, je peux l'utiliser dans le morceau d'enregistrements, mais comment puis-je le faire afin qu'il n'y ait pas de problème de mémoire insuffisante. – Anant

+0

bien, vous pouvez le faire aussi. Mais ne pensez-vous pas, vous l'avez défini à chaque fois que vous allez exécuter une requête. –

+0

C'est la raison pour laquelle je ne veux pas utiliser de requête. Et s'il vous plaît lire à nouveau le commentaire ci-dessus j'ai édité cela. Alors que vous pouvez obtenir ce que ma question est. – Anant

1

Vous pouvez utiliser une requête avec pagination dans ce but. Dans la classe Query, vous pouvez trouver les méthodes setFirstResult et setMaxResults qui peuvent vous aider à parcourir les enregistrements. Si vous devez charger tous les objets B et les stocker, vous pouvez ajuster les paramètres de mémoire de Java en définissant l'option -Xmx. Vous pouvez également essayer de déclarer une sorte de classe B réduite (par exemple ReducedB), qui contient uniquement les champs obligatoires, et utiliser l'itération avec la conversion B en ReducedB pour réduire l'utilisation de la mémoire.

Aussi vous pouvez vérifier this question. Je pense que c'est assez proche de ce que vous voulez.

P.S. La solution finale dépendra d'un problème particulier que vous voulez résoudre.

+0

Je l'ai fait exactement la même chose mais encore une fois je deviens hors de la mémoire. J'ai mis à jour mon code dans ma question afin que vous puissiez le vérifier. – Anant

+0

Je pense que la cause de «OUT OF MEMORY» est la même. Stockez-vous tous les objets B en même temps? Peut-être que les objets que vous récupérez dans DB ne sont pas collectés? Vous pouvez essayer l'outil 'jvisualvm' pour découvrir où la mémoire a disparu. – gkuzmin