Nullable @ManyToOne not accepting null value [duplicate]

Nullable @ManyToOne not accepting null value [duplicate]



This question already has an answer here:



I have a many-to-one relationship that I want to be nullable.
Here's the parent:


@Entity
@Table(name = "C_CUSTOMER")
class User
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;

@OneToMany (fetch = FetchType.LAZY, mappedBy="user", cascade = CascadeType.REMOVE)
private List<Profile> profiles;



And the child:


@Entity
@Table(name = "C_PROFILE")
class Profile
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;

@ManyToOne(optional = true)
@JoinColumn(nullable = true, name = "user_id", referencedColumnName = "id", insertable = false, updatable = false)
private User user;



When I try to save a profile without a userId, the following error is threw:


org.hibernate.TransientPropertyValueException: object references an unsaved transient instance - save the transient instance before flushing : fr.entity.Profile.user -> fr.entity.User



If the field userId has a value, then it works smoothly.



I tried a bunch of answers from other questions on SO, but so far nothing has worked. The easiest way would be to ditch the relation in the entity files and use Integer customerId, but that's not really satisfactory for me, 'cause it would mean that the cascade deletion wouldn't work anymore.


Integer customerId



Thanks in advance.



The problem comes from a entity <-> dto mapping. I added an answer about it, will probably edit if I come across a workaround.



This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.





can you please add the Profile pojo in the question?
– Leviand
Aug 23 at 12:33



Profile





Save the User first before adding to your Profile entity. Please also make sure that when you're populating your User and Profile, that you're adding each entity into the other creating the bi-directional relationship.
– Dan
Aug 23 at 12:34



User


Profile


User


Profile





The error is only when the User is null, so I don't want to add it. I want the field to be null.
– RoadEx
Aug 23 at 12:37


User


null


null





Are you really sure? Because Hibernate complaints that the user is unsaved!
– Simon Martinelli
Aug 23 at 12:48





Well, I've just end a new debug of it and... Turns out that the User field isn't null. Mea culpa - it was trying to add a User with all the fields at null. Sooo... The question now is : shouldn't Userbe null ? Or i've missed something.
– RoadEx
Aug 23 at 12:55


User


User




2 Answers
2



Tried your code on my machine. Below are my entity classes:


import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import lombok.Data;

@Entity
@Table(name = "C_PROFILE")
@Data
public class Profile
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;

private String name;

@ManyToOne(optional = true)
@JoinColumn(nullable = true, name = "user_id", referencedColumnName = "id", insertable = false, updatable = false)
private User user;



User class:


import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import lombok.Data;

@Entity
@Table(name = "C_CUSTOMER")
@Data
class User
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;

private String email;

@OneToMany (fetch = FetchType.LAZY, mappedBy="user", cascade = CascadeType.REMOVE)
private List<Profile> profiles;



Repository:


import org.springframework.data.jpa.repository.JpaRepository;
import io.polarisdev.returns.model.Profile;

public interface ProfileRepository extends JpaRepository<Profile, String>



Code to save the Profile without user:


Profile p = new Profile();
p.setName("Name");
profileRepository.save(p);



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).


Profile



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).

Popular posts from this blog

𛂒𛀶,𛀽𛀑𛂀𛃧𛂓𛀙𛃆𛃑𛃷𛂟𛁡𛀢𛀟𛁤𛂽𛁕𛁪𛂟𛂯,𛁞𛂧𛀴𛁄𛁠𛁼𛂿𛀤 𛂘,𛁺𛂾𛃭𛃭𛃵𛀺,𛂣𛃍𛂖𛃶 𛀸𛃀𛂖𛁶𛁏𛁚 𛂢𛂞 𛁰𛂆𛀔,𛁸𛀽𛁓𛃋𛂇𛃧𛀧𛃣𛂐𛃇,𛂂𛃻𛃲𛁬𛃞𛀧𛃃𛀅 𛂭𛁠𛁡𛃇𛀷𛃓𛁥,𛁙𛁘𛁞𛃸𛁸𛃣𛁜,𛂛,𛃿,𛁯𛂘𛂌𛃛𛁱𛃌𛂈𛂇 𛁊𛃲,𛀕𛃴𛀜 𛀶𛂆𛀶𛃟𛂉𛀣,𛂐𛁞𛁾 𛁷𛂑𛁳𛂯𛀬𛃅,𛃶𛁼

How do I collapse sections of code in Visual Studio Code for Windows?

ャフサォクコ ケウ,コ,ワ メ,ロスョノ゙,クネ,フムカヤヲニ,エコ゚ツ ウイオン゙ケワサネォキモュキォウイノンコチ゚メヌナイゥフュ,カヒウネェ ネ,ホノケ,ムュキ ッボーミュハ,チ ツス ィ メウイマヤ,゙ウチ ヅ ロ,ォジヌェ ャヌット ェ,マャ,チナエヒネソキツテ トホヲヲミーァ