ManyToOne relationship is always null when finding entity in the same transaction
There are many questions about similar problems. For example @Transactional in bidirectional relation with Spring Data returns null and Hibernate: comparing current & previous record.
As long as you are within a single transaction you'll always get the same instance and no data is actually loaded from the database. And since (it seems at least) you never set the reference to the ModeratorEntity
it stays null
.
Once you are in a new transaction the database gets accessed and JPA populates a new instance, now including a ModeratorEntity
reference.
The possible fixes therefore are:
Instead of an id let
moderatorService.save
return an entity and set that in theConversation
. You might as well drop themoderatorId
. This is the idiomatic way to do things with JPA.Perform the query in a separate transaction. Springs
TransactionTemplate
might come in handy. While this does work it causes JPA internals to bleed into your application which I recommend to avoid.
JPA @OneToMany & @ManyToOne null
Default value for fetchType
in @OneToMany
is FetchType.LAZY
.
make it EAGER
fetch.
@OneToMany(fetch = FetchType.EAGER, mappedBy = "product")
You'll find one join
in the query for picking images.
@OneToMany
Value null in all relations ManyToOne with hibernate
I've solved substituting @JoinColumn(insertable=false, updatable=false)
from false
to true
. This change allow hibernate to insert and update the wanted value.
Spring Data JPA - ManyToOne null
The problem is you are not setting the owner of the car via car.setOwner(...)
.
And also since you have cascade=CascadeType.ALL
on the OneToMany
annotation, you don't need to persist individual cars first and then the owner.
Just calling the personRepository.save(person);
should be enough.
So with the above changes, you code :
Car car1 = new Car();
Car car2 = new Car();
Person person = new Person();
car1.setName("Ferrari");
car2.setName("Porsche");
person.setName("Person Name");
person.getCars().add(car1);
person.getCars().add(car2);
car1.setOwner(person);
car2.setOwner(person);
personRepository.save(person);
And one more thing, you need to modify the toString method of Car
object. Person object's toString is calling Car's toString which internally is calling Person
toString again. This would lead to StackOverflowException
. Consider not printing the entire Person object
in the Car toString()
method.
May be Car [id=" + id + ", name=" + name + ", owner=" + owner.getName() + "]
** UPDATE **
If you are looking for a specific solution where you want to ensure the Car owner is populated in DB without making a call to car.setOwner(...)
method then you could update the OneToMany
mapping as below:
@OneToMany(cascade=CascadeType.ALL)
@JoinColumn(name="owner")
private Set<Car> cars = new HashSet<>();
Basically, mappedBy
is the one which decides who is the owner of the bidirectional relationship. In the first case, you have mentioned ownership of the relationship is owned by Car
entity via mappedBy
attribute. So unless we set the owner on the car object the ORM will not populate the owner
column.
With the second approach of removing the mappedBy, the oneToMany
becomes the owner of the relationship and so once you add to the car list of the Person, that person id will be used as the owner and will be populated in the DB against the owner column of the Car.
But, in the second case, and extra update is fired to update the owner column, apart ftom the normal insert, and so the owner column should be nullable.
Nullable @ManyToOne not accepting null value
So, after some digging inside the generated files: there's no solution to it (for now). The problem comes from a mapping between entity <-> dto, using mapstruct: having not mentioned this step, no wonder it wasn't working like it should for me... Well, the profile mapper contains this:
protected User profileToUser(Profile profile) {
if ( profile == null ) {
return null;
}
User user = new User();
User.setId(profile.getUserId());
return user;
}
Meaning I need to reassign a null value before saving the Profile
. There is apparently a ticket about this on the github, so wait and see. Seems like there's some suggestions too to make it work, so if I come across one that work, i'll edit this answer (unless someone answer with a solution before).
EDIT
After a few researches on the mapstruct git and SO, I came across a solution that work, though it's not really elegant.
@AfterMapping
public Profile doAfterMapping(@MappingTarget Profile entity) {
if (entity != null && entity.getUser().getId() == null) {
entity.setUser(null);
}
return entity;
}
So... I'll put the question in duplicate. Thanks a bunch to the ones that helped me (though I wouldn't have need to post if I had been more vigilant).
How do I echo out table <tr> horizontally instead of vertically with while-loop?
As the comment says, a <tr>
is a Table Row, which means it will create a new row vertically when displayed. The code below puts everything in one row, which will display it horizontally.
<table style="width:100%">
<tr>
<?php
while($row = mysqli_fetch_array($result)){
echo "<td>$row['user'] </td>";
}
?>
</tr>
</table>
Related Topics
How to Indicate to Spring Boot to Use Utc Time Zone for Date Parameters
How to Check Hikaricp Connection Pooling Is Working or Not in Java
Checking If a String Contains a Dot
Javac: File Not Found: First.Java Usage: Javac <Options> <Source Files>
Spring - Read Property Value from Properties File in Static Field of Class
Spring-Data-Jpa Repository - Underscore on Entity Column Name
Log File Is Created But File Is Empty
Delete Everything After Part of a String
How to Append a Query Parameter to an Existing Url
How to Store Original Date/Time Without Timezone Calculation to Mongodb
Spring Kafka - How to Reset Offset to Latest With a Group Id
Gradle Java9 Could Not Target Platform: 'Java Se 9' Using Tool Chain: 'Jdk 8 (1.8)'
Adding a Custom Http Header to a Spring Boot Ws Call (Wstemplate)
Autosize Column Width Using Poi
Jdk Tools.Jar as Maven Dependency