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
}
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.
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With