views:

98

answers:

3

Hi guys,

I managed (as you can see in older posts from me) to insert a onetomany relation through hibernate. My two entity classes look like following:

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 (which is a child of project. One project can have many applications, but one application belongs to just one project)

@Entity
public class Application {

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

So far, insertion of data works well. But getting data out of my database is the problem. I tried two ways:


Way 1: I retrieve a Project and try to get Applications out of the list attribute. But unfortunately Application entities are in a 'storedSnapshot', which seems pretty wrong to me. Here is a screenshot from my debug screen:

alt text

Actually that way works! I did some mistakes somewhere else...


Way 2: I try to retrieve a list of all applications via sql query:

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 throws strange exception -.-

org.hibernate.QueryException: could not resolve property: project_id of: de..common.entities.Application [from de..common.entities.Application a where a.project_id=1 ]

Problem with way 2 is that that I mix up SQL and HQL.


A little help for a hibernate beginner would be great :-) Cheers..

+1  A: 

For way 1: I don't know about StoredSnapshot, but try setting the FetchType for your applications List to "EAGER". Maybe that would fix it.

For way 2: You are creating a query on your datamodel and not so much on your database. So the fields should be the fields in your java mapping. In this case:

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

Note that the parameter you are passing to your function should be of type Project and not of type int.

Also, by using a named query you could do this:

 @NamedQuery(name="projectById",
             query="SELECT p FROM Project p"
                  + " LEFT JOIN FETCH applications"
            )
joeriMJ
Okay thank you I gonna try that. Seems like I confused SQL with HQL
Sven
+2  A: 

You should be able to access the applications by simply:

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

PersistentBag is implementing java.util.List so you should not care of its internals.

You will just need an open session to do that, otherwise a LazyInitializationException will be thrown.

Bozho
Actually it works! My mistake must be somewhere else, sry for your time...
Sven
+2  A: 

I try to retrieve a list of all applications via sql query (...) which throws strange exception

The exception is not strange and is exactly telling you what is wrong: Application doesn't have any project_id property, which is true (project_id is a database column).

Your query is not a SQL query, it's a JPQL query. JPQL queries are performed against entities (objects) and their associations. So you need to think object and associations.

In your case, (assuming you don't already have a Project instance but only a project id), you could do something like this:

Query q = session.createQuery("FROM Application a WHERE a.project.id = :id");
q.setParameter("id", project_id);
List<Application> applications = (List<Application>) q.list();
Pascal Thivent
How easy the world can be^^
Sven
@Sven isn't it?
Pascal Thivent
@Pascal Not if you are a beginner with all the frameworks and languages ;-)
Sven