hibernate-013: Can You Mix Unidirectional and Bidirectional @OneToMany & @ManyToOne?

Hunor Vadasz-Perhat - Feb 10 - - Dev Community

๐Ÿš€ Can You Mix Unidirectional and Bidirectional @OneToMany & @ManyToOne?

โœ… Yes, you can! You can choose:

  • @ManyToOne without @OneToMany โ†’ Unidirectional
  • @ManyToOne with @OneToMany(mappedBy) โ†’ Bidirectional

๐Ÿ“Œ Mixing Unidirectional & Bidirectional Approaches

Scenario @ManyToOne Used? @OneToMany Used? Direction Type
โœ… Best Practice โœ… Yes โœ… Yes (mappedBy) Bidirectional
โœ… Alternative โœ… Yes โŒ No Unidirectional (@ManyToOne only)

1๏ธโƒฃ Example: @ManyToOne Without @OneToMany (Unidirectional)

โœ… Best for queries from Employee โ†’ Department but NOT the other way around.

@Entity
public class Employee {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;

    @ManyToOne
    @JoinColumn(name = "department_id") // โœ… Foreign key in Employee table
    private Department department;
}

@Entity
public class Department {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
}
Enter fullscreen mode Exit fullscreen mode

โœ… Queries:

  • employee.getDepartment(); (Works โœ…)
  • department.getEmployees(); (Not possible โŒ - No @OneToMany)

๐Ÿš€ Use case: If you only need to retrieve an employee's department, but NOT employees from a department.


2๏ธโƒฃ Example: @ManyToOne + @OneToMany(mappedBy) (Bidirectional)

โœ… Best if you need queries in both directions.

@Entity
public class Employee {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;

    @ManyToOne
    @JoinColumn(name = "department_id") // โœ… Foreign key in Employee table
    private Department department;
}

@Entity
public class Department {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;

    @OneToMany(mappedBy = "department") // โœ… Refers to Employee.department
    private List<Employee> employees;
}
Enter fullscreen mode Exit fullscreen mode

โœ… Queries:

  • employee.getDepartment(); (Works โœ…)
  • department.getEmployees(); (Works โœ…)

๐Ÿš€ Use case: If you need to retrieve both:

  • All employees in a department
  • An employeeโ€™s department

๐ŸŽฏ Final Recommendation

When to Use Use @ManyToOne Only (Unidirectional) Use @ManyToOne + @OneToMany (Bidirectional)
โœ… Simple querying (best performance) โœ… Yes โŒ No
โœ… Only querying child โ†’ parent โœ… Yes โŒ No
โœ… Need parent โ†’ child queries โŒ No โœ… Yes
โœ… Avoiding unnecessary complexity โœ… Yes โŒ No

โœ… Best Practice:

  • Use @ManyToOne by itself (Unidirectional) if querying only from child โ†’ parent.
  • Use @ManyToOne + @OneToMany(mappedBy) (Bidirectional) if querying both ways.
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .