One-to-One Mapping in JPA – Complete Guide with Cascade, Fetch & JSON Issues One-to-One mapping in JPA is used when one entity is associated with exactly one in

 


One-to-One Mapping in JPA – Complete Guide with Cascade, Fetch & JSON Issues

One-to-One mapping in JPA is used when one entity is associated with exactly one instance of another entity. This relationship is very common in real-world systems such as:

  • User → Address
  • Employee → Passport
  • Customer → Profile

Let’s understand it properly with practical examples.


OneToOne – Unidirectional Mapping

In unidirectional mapping, only one entity knows about the other.

@Entity
@Table(name = "user_details")
public class UserDetails {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @OneToOne(cascade = CascadeType.ALL)
    private UserAddress userAddress;
}

Here:

  • UserDetails knows about UserAddress
  • UserAddress has no idea about UserDetails

This is the simplest and most commonly used form.


How Foreign Key is Created

Hibernate automatically creates a foreign key column using this rule:

<field_name>_id

So for:

private UserAddress userAddress;

Hibernate creates:

user_address_id

Custom Foreign Key using @JoinColumn

If you want full control:

@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "address_id", referencedColumnName = "id")
private UserAddress userAddress;

Now the foreign key will be:

address_id

Composite Key Reference

If the child entity uses a composite key, you must map all key columns:

@OneToOne
@JoinColumns({
   @JoinColumn(name="address_street", referencedColumnName="street"),
   @JoinColumn(name="address_pin_code", referencedColumnName="pinCode")
})
private UserAddress userAddress;

Cascade Types – The Most Important Concept

Cascade means:
What happens to the child when parent changes?

Cascade Meaning
PERSIST Save child automatically
MERGE Update child automatically
REMOVE Delete child automatically
REFRESH Reload child from DB
DETACH Stop tracking child
ALL All of the above

Most Used Cascade Combination

In real projects, best balance is:

@OneToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE})

Why?

  • Allows insert and update
  • Prevents accidental delete of child

Eager vs Lazy Loading

Type Meaning
EAGER Loads child immediately
LAZY Loads child only when accessed

Default:

  • OneToOne → EAGER
  • OneToMany → LAZY

You can control it:

@OneToOne(fetch = FetchType.LAZY)

Lazy Loading JSON Problem

When using LAZY, GET APIs often fail with errors like:

could not initialize proxy – no session

Because Jackson tries to serialize an object that is not loaded.

Wrong solution (quick hack)

@JsonIgnore

Correct solution (professional)

Use DTO.


DTO – Best Practice for REST APIs

Never return entities directly.

Instead:

class UserDTO {
   private String name;
   private String city;
}

Map entity → DTO in service layer.

This avoids:

  • Lazy loading errors
  • Infinite recursion
  • Exposing DB structure

Bidirectional OneToOne

Both entities know each other:

class UserDetails {
   @OneToOne
   private UserAddress userAddress;
}

class UserAddress {
   @OneToOne(mappedBy="userAddress")
   private UserDetails userDetails;
}

Still only one foreign key in DB.


Infinite Recursion Problem

Bidirectional mapping causes:

User → Address → User → Address → …

Solutions

Option 1 (old style)

@JsonManagedReference
@JsonBackReference

Option 2 (best modern solution)

@JsonIdentityInfo(
  generator = ObjectIdGenerators.PropertyGenerator.class,
  property = "id"
)

Jackson tracks objects using ID and avoids looping.


Real-World Best Practices

Scenario Recommendation
REST APIs Always use DTO
Banking systems Avoid Cascade.REMOVE
High traffic apps LAZY + DTO
CRUD projects PERSIST + MERGE
Microservices Never expose entities

Interview One-Liners (Gold)

Never expose JPA entities in REST APIs. Always use DTOs.

Avoid Cascade.REMOVE in production systems.

Bidirectional mapping does not create two foreign keys.

Lazy loading + Jackson = error unless handled properly.


 

Leave a Reply