Cannot make @ManyToOne relationship nullable

老子叫甜甜 提交于 2019-11-27 20:10:46

I found the solution to my problem. The way the primary key is defined in entity Customer is fine, the problem resides in the foreign key declaration. It should be declared like this:

@ManyToOne
@JoinColumn(columnDefinition="integer", name="customer_id")
private Customer customer;

Indeed, if the attribute columnDefinition="integer" is omitted the foreign key will by default be set as the source column: a not-null serial with its own sequence. That is of course not what we want as we just want the to reference the auto-incremented ID, not to create a new one.

Besides, it seems that the attribute name=customer_id is also required as I observed when performing some testing. Otherwise the foreign key column will still be set as the source column. This is a strange behavior in my opinion. Comments or additional information to clarify this are welcome!

Finally, the advantage of this solution is that the ID is generated by the database (not by JPA) and thus we do not have to worry about it when inserting data manually or through scripts which often happens in data migration or maintenance.

oschlueter

I came across this problem but I was able to solve it this way:

@ManyToOne
@JoinColumn(nullable = true)
private Customer customer;

Maybe the problem emerged from declaring @ManyToOne(optional = true)

That is very weird.

In JPA nullable parameter is true by default. I use this kind of configuration all the time and it works fine. If you try to save entity it should be successful.

Did you try to delete table that is created for this relationship? Maybe you have legacy table with that column?

Or maybe you should try to find solution on other chunks of code, because this is proper configuration.

Note: I have tried this configuration on PostgreSQL with JPA2 and Hibernate.

EDIT

In that case maybe you can try a little bit different definition of primary key.

For example you can use definition like this:

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column()
private Long id;

and postgresql will generate

id bigint NOT NULL
-- with constraint
CONSTRAINT some_table_pkey PRIMARY KEY (id)

If this is good enough you can try this solution.

within transaction but before the save operation, explicitly set the foreign key column value as null. By this hibernate ,never perform select queries for this foreign key related table and don't throw the exception "save the transient instance before flushing". if you want to set "null value " conditionally, then perform 1. fetch & set the value using repo call get/ find 2. then check the fetched value for the condition and set it to null accordingly .pasted the code below which is tested and found working

//  Transaction Start 

   Optional<Customer> customerObject = customerRepository.findByCustomerId(customer.getCustomerId())

   if(customerObject.isPresent())yourEnclosingEntityObject.setCustomer(customerObject)}

   else {yourEnclosingEntityObject.setCustomer(null)}

   yourEnclosingEntityObjectRepository.save(yourEnclosingEntityObject)

//  Transaction End
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!