简体   繁体   中英

JPA @OneToMany with 1 - 1..* relationship

How to properly map @OneToMany relationship where to create entity, on @One side of @OneToMany relationship, it is required to have atleast one entity from @Many side but entity on @Many side also requires entity on @One side to exist? To put this nightmare of a sentence simply, this is the scenario I have:

This is what I want:

[ENTITY A] 1 <-----> (1..*)[ENTITY B]

At the moment I have this:

[ENTITY A] 1 <-----> (0..*)[ENTITY B]

Which is easily done like this.

@OneToMany(cascade=CascadeType.ALL, mappedBy="customer")
public Set<Agreement> agreements = new HashSet<>();

and

@ManyToOne
@JoinColumn(name = "CUSTOMER_ID", nullable=false)
private Customer customer;

So the problem is my CUSTOMER table has no column corresponding to AGREEMENT table therefore I can't enforce rule of creating Customer only when Agreement is given. At the moment I can only setup rule to create Agreement when Customer is given because AGREEMENT table has column corresponding to CUSTOMER tabel, which is easily done by nullable=false condition.

It depends very much on what type of relationship you want to enforce. If the Agreement can exist independently from the Customer then this mean that the customer_id in agreement must be nullable.

If the Agreement can not exist independently this presumes that the customer id is not nullable in which case the Agreement can not be created in first place without the customer being created. This mean you have stronger association in between the customer and the corresponding Agreement.

Once we define that we have a relationship that is strong we need to investigate how strong it really is and who will own whom. Normaly the it is the Many side that owns the relationship and the updates are happening through the many side. This mean that your JoinColumn needs to be on the MANY and the mapped by needs to be on the ONE side.

It is interesting case when the ownership is inverse when the ONE side actually owns the relationship in this case the foreign key on the many side can not be NULL because there is no way for the owning ONE side to know what the MANY side key is.

JPA doesn't provide a way to validate this, but Hibernate Validator does:

@NotNull
@Size(min=1)
public Set<Agreement> agreements = new HashSet<>();

Then you have to manually test it via the Validator:

ValidatorFactory validatorFactory = Validation.buildDefaultValidatorFactory();
Validator validator = validatorFactory.getValidator();
validator.validate(customer)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM