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 @OneToManyUnidirectional
  • @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 EmployeeDepartment 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
喜欢就支持一下吧
点赞14 分享
Flat rich prosperous time in vain to develop a group of coward, hardship is the mother of strong forever.
平富足的盛世徒然养成一批懦夫,困苦永远是坚强之母
评论 抢沙发

请登录后发表评论

    暂无评论内容