Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring/Hibernate: Bidirectional Mapping without synchronization for JPQL queries only

In a bidirectional mapping between entities (e.g. @ManyToOne@OneToMany), the counterpart needs to be synchronized on every change, especially when using a 2nd level cache. This is usually done with helper methods. Those helper methods do not perform well if the Many part contains a lot of entries, because the whole set is fetched each time. A simple example would be an entity Store which has n Products, whereas n is very large. Adding a new Product to the Store would require the Store to fetch the whole list of Products to finally add it to the set (see code example below).

One could argue, that when modelling such a relation it would be better represented with an unidirectional association from the Product to the Store. We are using many JPQL queries in our application though. In JPQL, it comes very handy to join entities from both sides.

Do you see any problems when mapping the @OneToMany relation in the Store entity, when Many actually means many and not just a few, and just make the field private, without getters and setters, provided that the whole relation is lazily fetched? As I understand, Hibernate just needs the field to map the relation. And if the set is private, no performance issues should occur?


The Product entity:

@Entity
@Table(name = "product")
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class Product {

  @ManyToOne(fetch = FetchType.LAZY)
  private Store store;

  // setter, getter, helper methods
}

The Store entity:

@Entity
@Table(name = "store")
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class Store {

  @OneToMany(mappedBy = "products", fetch = FetchType.LAZY)
  @Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
  private Set<Product> products;

  // setter, getter, helper methods
}
like image 522
ssc-hrep3 Avatar asked Apr 20 '18 15:04

ssc-hrep3


People also ask

What is necessary for maintaining a bidirectional relationship in a many-to-many relationship in Hibernate?

You just need to reference the name of the association attribute of the many side as the value of the mappedBy attribute and Hibernate has all the information it needs. That's all you need to do to define a bidirectional many-to-one association.

What is the use of @ManyToOne?

A ManyToOne relationship in Java is where the source object has an attribute that references another object, the target object. I.e. the rather typical Java case that one object holds a reference to another object. A ManyToOne relationship can be specified unidirectional.

What is bidirectional mapping in JPA?

The bidirectional Many-to-One association mapping is the most common way to model this relationship with JPA and Hibernate. It uses an attribute on the Order and the OrderItem entity. This allows you to navigate the association in both directions in your domain model and your JPQL queries.


1 Answers

No, there is nothing wrong with it, it's a technique I've used often as well. Of course just make sure that the field is not accessed reflectively in some context (like automatic toString builders and similar utilities you may be using).

Also, you don't need the @Cache annotation on it since you will never access the collection anyway, thus it will never be cached.

like image 76
Dragan Bozanovic Avatar answered Oct 24 '22 20:10

Dragan Bozanovic