2

there are two entity classes:

@Entity
public class Place implements Serializable {
    @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id;
    @OneToMany(mappedBy = "place")
    private List<Event> events = new ArrayList<Event>();
    private String name;
//getters setters
}
@Entity
public class Event implements Serializable {
    @Id @GeneratedValue(strategy=GenerationType.IDENTITY) private Long id;
    @OneToMany(mappedBy = "event" , cascade={CascadeType.PERSIST})
    private List<Participant> participants = new ArrayList<Participant>();
    @ManyToOne(optional=false,fetch=FetchType.EAGER) private Place place;
    private String name;
// getters setters
}

the generated tables:

mysql> desc EVENT;
+----------+--------------+------+-----+---------+----------------+
| Field    | Type         | Null | Key | Default | Extra          |
+----------+--------------+------+-----+---------+----------------+
| ID       | bigint(20)   | NO   | PRI | NULL    | auto_increment |
| NAME     | varchar(255) | YES  |     | NULL    |                |
| PLACE_ID | bigint(20)   | YES  | MUL | NULL    |                |
+----------+--------------+------+-----+---------+----------------+
mysql> desc PLACE;
+----------+--------------+------+-----+---------+----------------+
| Field    | Type         | Null | Key | Default | Extra          |
+----------+--------------+------+-----+---------+----------------+
| ID       | bigint(20)   | NO   | PRI | NULL    | auto_increment |
| LOCATION | varchar(255) | YES  |     | NULL    |                |
| NAME     | varchar(255) | YES  |     | NULL    |                |
+----------+--------------+------+-----+---------+----------------+
Now, I'll code some Java so the Place and Event tables looks in this way:
+----+--------+
| ID | NAME   |
+----+--------+
|  1 | Prague |
+----+--------+
+----+-------------+----------+
| ID | NAME        | PLACE_ID |
+----+-------------+----------+
|  1 | Programming |        1 |
+----+-------------+----------+

Now, I would like to pick a place and view all its events:

// there's an ejb talking with persistence layer 
Place p = ejb.getPlaceWithId(1);
and I would think that there's something more than empty collection in p.events, but there is not - based on my observations. Why?

ryskajakub
  • 6,351
  • 8
  • 45
  • 75

4 Answers4

2

Are you calling p.getEvents().size() or are you inspecting the attribute in a debugger? If it is in a debugger then you may be seeing the Lazy loading artifacts which will be empty until the collection is accessed. Try calling p.getEvents().get(0) and see what you get.

Gordon Yorke
  • 1,996
  • 11
  • 7
2

Now, I would like to pick a place and view all its events (...) and I would think that there's something more than empty collection in p.events, but there is not - based on my observations. Why?

My observations are that the events are LAZY in the code you're showing:

@OneToMany(mappedBy = "place")
private List<Event> events = new ArrayList<Event>();

So how did you come to the conclusion that they are empty when loading a given Place exactly? Did you try to call size() on the collection to force the loading (or to iterate on collection items)?

Regardless of the answer to the above question, my suggestions would be to

  • Activate SQL logging (and to run the queries in a SQL client if necessary) to see what is happening.
  • Maybe actually use a fetch join if you want to load the events eagerly:

    SELECT p FROM Place p join fetch p.events WHERE p.id = :id
    
Pascal Thivent
  • 562,542
  • 136
  • 1,062
  • 1,124
1

1)

@OneToMany(mappedBy = "place", fetch = FetchType.EAGER)
private List<Event> events = new ArrayList<Event>();

does it.

2) or

Place p = ejb.getPlaceWithId(1);
p.getEvents().size(); // will force the fetch
Igor Mukhin
  • 15,014
  • 18
  • 52
  • 61
0

There could be a problem in your EJB method getPlaceWithId - not sure how you're looking up your entities.

Jordan Allan
  • 4,408
  • 7
  • 32
  • 35