I have a parent (Program) pojo with a many-to-many relationship with their children (Subscriber).
The problem is when it serialises a Program, it also serialises the Program’s Subscribers, which involves serialising their Programs, which involves serialising their Subscribers, until it has serialised every single Program & Subscriber in the database.
The ERD looks like: Program <-> Subscriber
This means what was a tiny 17KB block of data (json) being returned has become a 6.9MB return. Thus in turn blows out the time to serialise the data and then return it.
Why is my parent returning children returning parents returning children? How can I stop this so I only get the Subscribers for each Program? I’m assuming I’ve done something wrong with my annotations, perhaps? I would like to maintain a many-to-many relationship but without this deeply nested data retrieval.
(Note: I have prior tried adding as many Lazy annotations I can find just to see if that helps. It doesn’t. Perhaps I’m doing that wrong too?)
Program.java
@Entity
@Table(name="programs")
public class Program extends Core implements Serializable, Cloneable {
...
@ManyToMany()
@JoinTable(name="program_subscribers",
joinColumns={@JoinColumn(name="program_uid")},
inverseJoinColumns={@JoinColumn(name="subscriber_uid")})
public Set<Subscriber> getSubscribers() { return subscribers; }
public void setSubscribers(Set<Subscriber> subscribers) { this.subscribers = subscribers; }
Subscriber.java
@Entity
@Table(name="subscribers")
public class Subscriber extends Core implements Serializable {
...
@ManyToMany(mappedBy="subscribers")
public Set<Program> getPrograms() { return programs; }
public void setPrograms(Set<Program> programs) { this.programs = programs;
}
Implementation
public Collection<Program> list() {
return new Programs.findAll();
}
Both Bozho and ponkin are on the right track. I needed to stop serialising the data down the wire but the big problem is I am unable to change the pojo -> toJSON class/method where the serialisation takes place. I was also worried about investing time on the toJSON() method considering I was taking such a performance hit at the point of serialisation I wanted a fix that would occur before I had the data rather than afterwards.
Also due to the nature of the Many-to-Many Bidirectional design I had listed I was always going to have this cyclic programs/subscribers/programs/… problem.
Resolution: (for now atleast) I have removed the Subscriber.getProgram() method and created a finder method on the ProgramDAO which returns the Programs by Subscriber.
For any CRUD work I think I’m just going to have to loop over Programs.getSubscribers, or write more hql helper methods.