2010-09-08 16 views
1

J'ai réussi (comme vous pouvez le voir dans les messages plus anciens de moi) pour insérer une relation onetomany par Hibernate. Mes deux classes d'entités ressemblent à ce qui suit:Hibernate liste de récupération de onetomany

Project.java:

@Entity 
public class Project { 

@Id 
@GeneratedValue(strategy = GenerationType.IDENTITY) 
private int id; 
    @OneToMany(cascade = CascadeType.ALL, mappedBy="project") 
    @OrderColumn(name = "project_index") 
    List<Application> applications; 
.... 

Application.java (qui est un enfant du projet Un projet peut avoir de nombreuses applications, mais une application appartient à un seul projet.)

@Entity 
public class Application { 

@Id 
@GeneratedValue(strategy = GenerationType.IDENTITY) 
private int id; 
    @ManyToOne 
    @JoinColumn(name = "project_id") 
    private Project project; 
... 

Jusqu'à présent, l'insertion de données fonctionne bien. Mais obtenir des données sur ma base de données est le problème. J'ai essayé deux façons:


Way 1: Je récupérer un projet et essayer d'obtenir des applications de l'attribut liste. Mais malheureusement, les entités de l'application sont dans un 'storedSnapshot', ce qui me semble plutôt faux. Voici une capture d'écran de mon écran de débogage:

alt text

fait que les travaux de façon! Je l'ai fait quelques erreurs à un autre endroit ...


Way 2: J'essaie de récupérer une liste de toutes les applications via requête SQL:

public List<Application> getApplications(int project_id) { 
    Session session = HibernateUtil.getSessionFactory().getCurrentSession(); 
    session.beginTransaction(); 
    List<Application> applications = session.createQuery("from Application a where a.project_id=" + project_id + " ").list(); 
    return applications; 
} 

..which lance exception étrange -. -

org.hibernate.QueryException: ne pouvait pas résoudre la propriété: project_id de: de..common.entities.Application [from de..common.entities.Application a where a.project_id=1 ]

Problème avec la voie 2 est que je mélange SQL et HQL.


Un peu d'aide pour un débutant de mise en veille prolongée serait grand :-) .. Vive

+0

ce qui est dans 'bag'? – Bozho

+0

Expliquez ce qui ne va pas avec storedSnapshot? – wds

+0

@Bozho: de quel sac parlez-vous – Sven

Répondre

4

Vous devriez être en mesure d'accéder aux applications simplement:

List<Application> applications = project.getApplications(); 

PersistentBag est mise en œuvre java.util.List vous ne devriez pas prendre soin de ses internes.

Vous aurez juste besoin d'une session ouverte pour le faire, sinon un LazyInitializationException sera lancé.

+0

En fait cela fonctionne! Mon erreur doit être ailleurs, sry pour ton temps ... – Sven

1

Way 1: Je ne sais pas StoredSnapshot, mais essayez de régler la FetchType pour vos applications Liste à "EAGER". Peut-être que ça réglerait ça.

Pour la méthode 2: vous créez une requête sur votre modèle de données et pas tellement sur votre base de données. Les champs doivent donc être les champs de votre mapping java. Dans ce cas:

 
List applications = session.createQuery("from Application a where a.project=" + project).list(); 

Notez que le paramètre que vous passez à votre fonction doit être de type Projet et non de type int.

également, à l'aide d'une requête nommée, vous pouvez le faire:

 
@NamedQuery(name="projectById", 
      query="SELECT p FROM Project p" 
        + " LEFT JOIN FETCH applications" 
      ) 
+0

D'accord, je vais essayer ça. On dirait que j'ai confondu SQL avec HQL – Sven

2

J'essaie de récupérer une liste de toutes les applications via requête SQL (...) qui jette étrange exception

L'exception n'est pas étrange et vous dit exactement ce qui est faux: Application doesn » t possède une propriété project_id, ce qui est vrai (project_id est une colonne de base de données).

Votre requête n'est pas une requête SQL, c'est une requête JPQL. Les requêtes JPQL sont exécutées contre entités (objets) et leurs associations. Donc vous devez penser à l'objet et aux associations.

Dans votre cas, (en supposant que vous ne l'avez pas déjà une instance Project mais seulement un projet id), vous pouvez faire quelque chose comme ceci:

Query q = session.createQuery("FROM Application a WHERE a.project.id = :id"); 
q.setParameter("id", project_id); 
List<Application> applications = (List<Application>) q.list(); 
+0

Comme le monde peut être facile ^^ – Sven

+0

@Sven n'est-ce pas? –

+0

Pas si vous êtes un débutant avec tous les cadres et les langues ;-) – Sven