I have a FK that recursively points to the very same entity, but it can't be nullable
Person entity:
@OneToMany(fetch = FetchType.LAZY)
@JoinColumn(name = "personId", referencedColumnName = "managerId", updatable = false, insertable = false, nullable = true)
private List<Person> managers;
But this is returning null instead of an empty list when the join is null. The problem is that I am not sure it's an error, or a design fault. While debugging, child person shows managers as a persistent bag, but orphan persons have no empty persistent bag but a null value.
But in this question, a user affirms the list should always be initialized: To initialize or not initialize JPA relationship mappings?
Just for your info, theres no LazyLoadingExceptions as all the code is within a @Transactional
In this other question (JPA OneToMany - Collection is null) there's an explanation about JPA using noargs constructor and setting fields directly from db, so I am wondering if the problem is that JPA sets the list to null because the fb returns the join column as null. If that were the case, would it be a way to tell JPA to send an empty list instead of null?
The code for fetching is a test:
@Test
@Transactional
public void fetchManagersOfCEO(){
Person person = this.personRepository.findOne(1L);
assertThat(result.getManagers().size()).isEqualTo(0);
}
This return expected managers when the id is the one of an employee with managers above
P.S> After a lot of debugging, the problem is that JPA is setting the collection to null, no "COLLECTION NOT NULL" ObjectMarker, and empty CollectionReferenceInitializers
I don't like it but the only way I found to work out the issue is:
public List<Person> getManagers(){
return Optional.ofNullable(this.managers).orElseGet(ArrayList::new);
}
Just do this:
@OneToMany(fetch = FetchType.LAZY)
@JoinColumn(name = "personId", referencedColumnName = "managerId", updatable = false, insertable = false, nullable = true)
private List<Person> managers = new ArrayList<>();
Let's say we have entity A that has one to many entity B.
You can then replicate your problem by:
This is because Hibernate refers to the same object in a single transaction and the object has null as a list of B.
However, if you are in two separate transactions or if you manually clear the session (SessionFactory.clear or EntityManager.clear) then the list should properly be initialized with an empty persistent bag.
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