IntelliJ can't find inverse attribute in many-to-many relationship when the inverse attribute has final keywords

Viewed 60

Let's suppose we have two entities in many-to-many bi-directional relationships, Student and Subject.

@Getter
@Entity
public class Student {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Setter
    private String name;

    @JoinTable(
            name = "student_subject",
            joinColumns = @JoinColumn(name = "student_id"),
            inverseJoinColumns = @JoinColumn(name = "subject_id")
    )
    @ManyToMany(cascade = CascadeType.ALL)
    private final Set<Subject> subjects = new LinkedHashSet<>();

// constructors and etc.
}
@Getter
@Entity
public class Subject {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Setter
    private String name;

    @ManyToMany(mappedBy = "subjects")
    private final Set<Student> students = new LinkedHashSet<>();

// constructors and etc.
}

Each collection field is set to final and has no setter. This is intentional design to prevent it from being accidentally re-initialized to other collection instance after the persistence context takes care of it.

You can test if the entities above are working using this simple repository interface:

public interface StudentRepository extends JpaRepository<Student, Long> {}

and the following test works:

@Test
void studentMattStudiesMathAndHistory() {
    Student student = new Student("Matt");
    student.getSubjects().add(new Subject("Math"));
    student.getSubjects().add(new Subject("History"));
    studentRepository.saveAndFlush(student);
}

So it looks like there's no trouble in entity design. However, IntelliJ seems to have different thought about this.

enter image description here

IntelliJ tells me that it can't find inverse attribute, in this case it's subjects field and is obviously existent right inside the Student. Well I figured out how to fix this red underline. Just remove final keyword like this:

private Set<Subject> subjects = new LinkedHashSet<>();

and the red underline is gone. Of course there's still no setter for it, so IntelliJ tells me to put the final keyword back for the code suggestion.

enter image description here

So the question is, why IntelliJ is not able to find the inverse attribute subjects? Is it a bug, or am I missing something?

Version spec.

  • Spring Boot: 2.7.2
  • IntelliJ: 2022.2
1 Answers

As per JPA documentation 'No methods or persistent instance variables must be declared final'. remove final keyword from variable.

for details check

Related