简体   繁体   中英

Why can't we make a relationship attribute in spring data JPA final as well?

An Owner entity has a @ManyToOne - @OneToMany relationship with the teacher entity. When I annotate each like this

@Entity
public class Product {

... 

@ManyToOne(cascade = MERGE)
private final Owner owner;

On the other side, in the Owner Class,

@Entity 
public class Owner {

...

@OneToMany(mappedBy = "owner", cascade = MERGE)
private final List<Product> products;

What happens now is that "owner" in the line mappedBy = "owner" turns red. Hovering over it, I get the error that the owner attribute cannot be found.

The error: Cannot find inverse attribute

The solution was simply to remove the final keyword in the attribute owner in the Product class.

It becomes private Owner owner and the error disappears. I don't understand why adding the keyword final causes this problem.

Why does this happen? Is there a workaround? Can I still make the owner attribute final?

The main idea from the getgo was to make the product class immutable. While this is a challenge, I've managed to find a workaround for most things, but I didn't know how to fix this problem.

JPA does not support immutability. A JPA entity does require a default constructor and getters and setters for properties. And the fields must not be final.

Technically it would be possible to implement an ORM that ignores final attributes but why should it?

The keyword final says: This gets assigned a value at construction time and never changes after that. This is just not true for JPA entities which get constructed via no-args-constructor and then populated in second step.

If you are looking for an ORM that has better support for immutable classes (constructor with arguments, "wither" methods) you might want to check out Spring Data JDBC.

Full disclosure: I'm Spring Data developer working on both Spring Data JPA and Spring Data JDBC.

I think you have understood immutability concept wrong. Immutability is a concept being forced by the Java language. For example String class is immutable because of the security, caching etc. But in your case Product is an entity class and if you save it in a persistent layer, it is already unique on it's own. So even if you make the Product class immutable, how are you going to keep that consistency during two application loads?. If you are trying to make a Product having owned by only one owner, then do a db check rather than trying to make it immutable in memory.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM