For Hibernate users, there is undocumented rule found by trial and error based on log messages and analyzing generated queries:

Formalizing this picture, you need to use a linking table named : table1_table2 and use ids in linking table like these ones: table1_table1Id and table2_table2Id
By doing so, Hibernate understand what's going on without further explanation and providing @JoinTable info.
@Data
@Entity
@Table(name="course")
public class Course {
@Id
@GeneratedValue(strategy= GenerationType.AUTO, generator="native")
@GenericGenerator(name = "native", strategy = "native")
private Long courseId;
@Column(name="name")
private String name;
}
@Data
@Entity
@Table(name="student")
public class Student {
@Id
@GeneratedValue(strategy= GenerationType.AUTO, generator="native")
@GenericGenerator(name = "native", strategy = "native")
private Long studentId;
@Column(name="name")
private String name;
@Column(name="class")
private String className;
@ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
private List<Course> course;
}
If you stick to this mapping, all the JPQL queries work smoothly and as expected generating correct SQL queries with outer joins... Note, course without -s at the end! If you want courses anyways you should change fields name in joining table to table2s_table2Id and table itself to table2s
P.S. I haven't found any straightforward mentioning about this convention neither in JPA nor in Hibernate documentation (only in single example), and it can probably be changed in future releases, tested with Hibernate 5.2/5.3. However it gives a hint of how to name joining table and fields in it.