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.
<span>@Entity</span><span>public</span> <span>class</span> <span>Employee</span> <span>{</span><span>@Id</span><span>@GeneratedValue</span><span>(</span><span>strategy</span> <span>=</span> <span>GenerationType</span><span>.</span><span>IDENTITY</span><span>)</span><span>private</span> <span>Long</span> <span>id</span><span>;</span><span>private</span> <span>String</span> <span>name</span><span>;</span><span>@ManyToOne</span><span>@JoinColumn</span><span>(</span><span>name</span> <span>=</span> <span>"department_id"</span><span>)</span> <span>// Foreign key in Employee table</span><span>private</span> <span>Department</span> <span>department</span><span>;</span><span>}</span><span>@Entity</span><span>public</span> <span>class</span> <span>Department</span> <span>{</span><span>@Id</span><span>@GeneratedValue</span><span>(</span><span>strategy</span> <span>=</span> <span>GenerationType</span><span>.</span><span>IDENTITY</span><span>)</span><span>private</span> <span>Long</span> <span>id</span><span>;</span><span>private</span> <span>String</span> <span>name</span><span>;</span><span>}</span><span>@Entity</span> <span>public</span> <span>class</span> <span>Employee</span> <span>{</span> <span>@Id</span> <span>@GeneratedValue</span><span>(</span><span>strategy</span> <span>=</span> <span>GenerationType</span><span>.</span><span>IDENTITY</span><span>)</span> <span>private</span> <span>Long</span> <span>id</span><span>;</span> <span>private</span> <span>String</span> <span>name</span><span>;</span> <span>@ManyToOne</span> <span>@JoinColumn</span><span>(</span><span>name</span> <span>=</span> <span>"department_id"</span><span>)</span> <span>// Foreign key in Employee table</span> <span>private</span> <span>Department</span> <span>department</span><span>;</span> <span>}</span> <span>@Entity</span> <span>public</span> <span>class</span> <span>Department</span> <span>{</span> <span>@Id</span> <span>@GeneratedValue</span><span>(</span><span>strategy</span> <span>=</span> <span>GenerationType</span><span>.</span><span>IDENTITY</span><span>)</span> <span>private</span> <span>Long</span> <span>id</span><span>;</span> <span>private</span> <span>String</span> <span>name</span><span>;</span> <span>}</span>@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.
<span>@Entity</span><span>public</span> <span>class</span> <span>Employee</span> <span>{</span><span>@Id</span><span>@GeneratedValue</span><span>(</span><span>strategy</span> <span>=</span> <span>GenerationType</span><span>.</span><span>IDENTITY</span><span>)</span><span>private</span> <span>Long</span> <span>id</span><span>;</span><span>private</span> <span>String</span> <span>name</span><span>;</span><span>@ManyToOne</span><span>@JoinColumn</span><span>(</span><span>name</span> <span>=</span> <span>"department_id"</span><span>)</span> <span>// Foreign key in Employee table</span><span>private</span> <span>Department</span> <span>department</span><span>;</span><span>}</span><span>@Entity</span><span>public</span> <span>class</span> <span>Department</span> <span>{</span><span>@Id</span><span>@GeneratedValue</span><span>(</span><span>strategy</span> <span>=</span> <span>GenerationType</span><span>.</span><span>IDENTITY</span><span>)</span><span>private</span> <span>Long</span> <span>id</span><span>;</span><span>private</span> <span>String</span> <span>name</span><span>;</span><span>@OneToMany</span><span>(</span><span>mappedBy</span> <span>=</span> <span>"department"</span><span>)</span> <span>// Refers to Employee.department</span><span>private</span> <span>List</span><span><</span><span>Employee</span><span>></span> <span>employees</span><span>;</span><span>}</span><span>@Entity</span> <span>public</span> <span>class</span> <span>Employee</span> <span>{</span> <span>@Id</span> <span>@GeneratedValue</span><span>(</span><span>strategy</span> <span>=</span> <span>GenerationType</span><span>.</span><span>IDENTITY</span><span>)</span> <span>private</span> <span>Long</span> <span>id</span><span>;</span> <span>private</span> <span>String</span> <span>name</span><span>;</span> <span>@ManyToOne</span> <span>@JoinColumn</span><span>(</span><span>name</span> <span>=</span> <span>"department_id"</span><span>)</span> <span>// Foreign key in Employee table</span> <span>private</span> <span>Department</span> <span>department</span><span>;</span> <span>}</span> <span>@Entity</span> <span>public</span> <span>class</span> <span>Department</span> <span>{</span> <span>@Id</span> <span>@GeneratedValue</span><span>(</span><span>strategy</span> <span>=</span> <span>GenerationType</span><span>.</span><span>IDENTITY</span><span>)</span> <span>private</span> <span>Long</span> <span>id</span><span>;</span> <span>private</span> <span>String</span> <span>name</span><span>;</span> <span>@OneToMany</span><span>(</span><span>mappedBy</span> <span>=</span> <span>"department"</span><span>)</span> <span>// Refers to Employee.department</span> <span>private</span> <span>List</span><span><</span><span>Employee</span><span>></span> <span>employees</span><span>;</span> <span>}</span>@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.
原文链接:hibernate-013: Can You Mix Unidirectional and Bidirectional @OneToMany & @ManyToOne?
© 版权声明
THE END
暂无评论内容