Can a @Manytoone JPA Relation Be Null

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 the Conversation. You might as well drop the moderatorId. 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



Leave a reply



Submit