balteo
balteo

Reputation: 24679

Pros and cons of JPA bidirectional relationships

I am in situation whereby I need to change my JPA unidirectional relationships to become bidirectional (an Account entity has a list of Advertisements) so that given a Advertisement I can determine whether or not it belongs to an Account (for security reasons).

It seems that a cross-cutting concern has imposed a design decision on my application and I am not sure this is good.

Also, I don't know what the downsides of using bidirectional relationships are.

Can anyone please comment and advise?

Upvotes: 6

Views: 5879

Answers (2)

njeru
njeru

Reputation: 89

Another downside of bidirectional relationships is that it makes it easy to get yourself into infinite recursion with Jackson, Hibernate JPA, and/or Elasticsearch implementations. In each of your models, you will be maintaining instances of the other model. So for instance when you maintain an account, you must also maintain its advertisements.

Let's say that the application is serving a higher than moderate volume of requests on a busy day. What happens next is that the control will start looping back and forth between the methods of the instances that maintain their relationships, creating a new stack frame entry into your call stack for each loop. Each stack frame is holding references to the parameters of the methods, the local variables, and return addresses. The JVM quickly runs out of buffer in which to add new stack frames and you start experiencing Stackoverflow errors.

It's not always the case, but if you are dealing with an application that handles a high volume of persistence requests (as opposed to a high volume of data retrieval or data analytics requests), the benefits of bi-directional relationships fade quickly in the face of how much effort and thoroughness is needed to avoid Stackoverflow errors on your persistence layers.

Upvotes: 2

wypieprz
wypieprz

Reputation: 8229

Let me try to answer the question with an example:

@Entity
public clas Account {

    @OneToMany(mappedBy = "account") // is mappedBy really necessary ?
    private List<Advertisements> advertisements;
}

Unidirectional downsides:
Lack of mappedBy atribute leads to unidirectional one-to-many relationship and produces additional join table consisting of foreign keys. This is often treated as JPA pitfall and have negative impact on a performance at a database level (you have three tables instead of two).

@Entity
public clas Advertisements {

    @ManyToOne
    @JoinColumn(name="ACCOUNT_ID")
    private Account account; // is Account really necessary ?
}

Bidirectional downsides:
You can navigate from Advertisements to Account so in terms of JPA you have an access to a single-valued association path "SELECT adv.account FROM Advertisements adv". The assumption is you don't want to therefore one could say this may have a negative impact on a security at JPA level.

Upvotes: 6

Related Questions