Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Inner join in spring boot data jpa

I am using spring boot data jpa 1.4 and I'm fairly new to it. My table definition is here. Its fairly simple, there are 2 tables (Groups and Users).

  1. The group table contains group_id(primary key), group_name, group_active(values=Y/N). The group table can ideally have only one row which is has group_active to 'Y', the rest should have 'N'

  2. The user table contains user_id(primary key), user_name, group_id(foreign key from group).

Following are my entity classes

Group:

@Entity
@Table(schema = "HR",  name = "GROUPS")
public class Group {

    @Id
    @GeneratedValue(strategy = IDENTITY)
    @Column(name = "GROUP_ID")
    private Long id;

    @Column(name = "GROUP_NAME")
    private String name;

    @Column(name = "GROUP_ACTIVE")
    private String active;

User:

@Entity
@Table(schema = "HR", name = "USERS")
public class User {

    @Id
    @GeneratedValue(strategy = IDENTITY)
    @Column(name = "USER_ID")
    private Long id;

    @Column(name = "USER_NAME")
    private String name;

    @Column(name = "GROUP_ID")
    private Long groupId;

    @ManyToMany
    @JoinTable(
        schema = "HR",
        name = "GROUPS",
        joinColumns = {@JoinColumn(table = "GROUPS", name = "GROUP_ID", insertable = false, updatable = false)},
        inverseJoinColumns = {@JoinColumn(table = "USERS", name = "GROUP_ID", insertable = false, updatable = false)}
    )
    @WhereJoinTable(clause = "GROUP_ACTIVE='Y'")
    private List<Group> group;

Repository class:

public interface UserRepository extends CrudRepository<User, Long>{        
    List<User> findByName (String name);
}

Query: This is the query I want to execute, which is a simple inner join.

  SELECT U.*
  FROM HR.USER U, HR.GROUP G
  WHERE U.GROUP_ID=G.GROUP_ID
      AND G.GROUP_ACTIVE='Y'
      AND U.USER_NAME=?

What would be the correct way to write the @JoinTable or @JoinColumn such that I always get back one user that belongs to the active group with the name ?

like image 578
Adnan Mamajiwala Avatar asked Nov 08 '22 02:11

Adnan Mamajiwala


1 Answers

I have done some tests based on your set-up and the solution would need to use filters (assuming there is only one Group with Group_Activity = 'Y'):

Group Entity

@Entity
@Table(schema = "HR",  name = "GROUPS")
public class Group {

     @OneToMany(mappedBy = "group")
     @Filter(name = "activityFilter")
     private Set<User> users;

User Entity

@Entity
@Table(schema = "HR", name = "USERS")
@FilterDef(name="activityFilter"
       , defaultCondition="group_id = 
              (select g.id from groups g where g.GROUP_ACTIVE='Y')")
public class User {

@ManyToOne
@JoinColumn(name = "group_id")
private Group group;

When making a query

session.enableFilter("activityFilter");
session.createQuery("select u from Group g inner join g.users u where u.user_name = :userName");

Additionally if there are many groups with activity = 'Y' then try this:

@FilterDef(name="activityFilter"
       , defaultCondition="group_id in
              (select g.id from group g where g.GROUP_ACTIVE='Y')")
like image 142
Maciej Kowalski Avatar answered Jan 03 '23 22:01

Maciej Kowalski