DEV Community

Hunor Vadasz-Perhat
Hunor Vadasz-Perhat

Posted on

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

πŸš€ 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.

Top comments (0)

Sentry image

See why 4M developers consider Sentry, β€œnot bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more