Spring Data JPA: Implementing One To One Association

  • Post last modified:April 17, 2023
  • Reading time:3 mins read

Learn one-to-one associations, its advantage, and implementation

Introduction

  • In this article, we will learn about the one-to-one association, when to use them, and implement them using Spring data JPA using one example.

One-to-One relationship

  • Let’s say we user accounts table which includes info such as username, password, email, etc.
  • We have another table called permissions which has permission that can be granted to the account table for the app such as the admin console.
  • Now one account can only have one permission at a time which maps the relationship between the account and the permission table as one-to-one.
  • In a one-to-one relationship, one record in a table is associated with one and only one record in another table.
  • One advantage of the one-to-one association against keeping everything in one flat table is that now we can extend the table to more fields, providing the separation of concern.

Entities

  • Let’s create an entity for the account table. For Id, we are explicitly mentioning the sequence generator that we would like to use.
  • The entity contains all the fields that we saw in the table.
  • For the permission_id, we need to specify that this field is a join column and join type is one-to-one using @OneToOne. annotation.
@Entity
@Table(name="ACCOUNTS")
public class Account {
    @Id @GeneratedValue(strategy= GenerationType.SEQUENCE, generator = "accounts_seq")
    @SequenceGenerator(name = "accounts_seq", sequenceName = "accounts_seq", allocationSize = 1)
    @Column(name = "user_id")
    private int userId;
    private String username;
    private String password;
    private String email;
    private Timestamp createdOn;
    private Timestamp lastLogin;

    @OneToOne
    @JoinColumn(name = "permissions_id")
    private Permission permission;

   // getters, setters
}
  • Similarly, we need to create a permission table that contains necessary fields such as id along with its reference to the sequence generator and type of permission.
@Entity
@Table(name="PERMISSIONS")
public class Permission {

    @Id
    @GeneratedValue(strategy= GenerationType.SEQUENCE, generator = "permissions_id_sq")
    @SequenceGenerator(name = "permissions_id_sq", sequenceName = "permissions_id_sq", allocationSize = 1)
    private int id;

    private String type;
}

Business Logic Layer

  • Now our API consumer wants all the users along with their permission to be returned.
  • For that, we can inject AccountRepository and make JPA call to the database to get all the accounts.
@Autowired
private AccountRepository accountRepository;
  • account repository findAll will return all the accounts and now we can filter accounts to whom permission is not assigned, in order to return only accounts where permissions have been granted to the website
  • Collectors.toMap(Account::getUserId,Account::getPermission) will map the userId with the permission entity and return the Map instance to the controller.
public Map<Integer, Permission> getAccountsWithPermission(){

        return accountRepository
                .findAll()
                .stream()
                .filter(a->a.getPermission()!=null)
                .collect(Collectors.toMap(Account::getUserId,Account::getPermission));
    }
  • Now the controller is fed with appropriate data and it’s ready to return the output to the API client.
@GetMapping("/getPermissions")
    public Map<Integer, Permission> getAllAccountPermission(){
        return accountLogic.getAccountsWithPermission();
    }

  • We can check the result with Postman.

Conclusion

  • In this article, we learn about one-to-one association and how we can implement it using spring data jpa.
  • We also discuss the advantage of using one-to-one associations.

Before You Leave

Other Must-Read Articles

Leave a Reply