Невозможно сопоставить поля разных сущностей с отношениями многие ко многим - PullRequest
0 голосов
/ 17 июня 2020

Схема БД - 2 таблицы (пользователь и роль) имеют отношения «многие-ко-многим» и связаны промежуточной таблицей (user_role) в postgres. Я хочу получить все роли и имя человека, который их создал. Имя доступно в таблице пользователей, но все остальные детали находятся в таблице ролей. В таблице ролей есть поле created_by (User_id лица, создавшего роль).

Я пытаюсь создать запрос GET для просмотра всех ролей данного идентификатора с именем человека, который его создал

Класс сущности Users1. java

@Data
@Entity
@Table(name = "user")
public class Users1 {

@Id
@Column(name = "user_id")
private Long user_id;

@Column(name = "org_id")
private Long org_id;

@Column(name = "boss")
private Boolean boss;

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

@Column(name = "created_by")
private Long created_by;


@CreationTimestamp
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "created_on")
private Date created_on;

@ManyToMany(fetch = FetchType.LAZY,
        cascade = {CascadeType.ALL})
@JoinTable(name = "user_role",
    joinColumns = {@JoinColumn(name = "user_id")},
    inverseJoinColumns = {@JoinColumn(name = "created_by")})

private List<Role> roles = new ArrayList<Role>();

// Getters and Setters

Роль класса сущности. java

@Data
@Entity
@Table(name = "role")
public class Role implements Serializable {
private static final long serialVersionUID = -2343243243242432341L;

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "role_id")
private Long role_id;

@Column(name = "org_id")
private Long org_id;

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

@Column(name = "created_by")
private Long created_by;

@CreationTimestamp
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "created_on")
private Date created_on;

@ManyToMany(fetch = FetchType.LAZY,
        cascade = {CascadeType.ALL},
        mappedBy = "roles")

private List<Users1> users = new ArrayList<>();

// Getters and Setters

ролей. Класс репозитория

@Repository
@Transactional
public interface RolesRepository extends CrudRepository<Role,Long> {
    @Query(value ="select r.*,u.firstname as firstname 
    from user u 
    join user_role ur  on u.user_id = ur.user_id 
    join role r on ur.role_id = r.role_id 
    where(true = (select u.boss from user u  where u.user_id = ?2) and r.org_id = ?1)
    or 
    (false = (select u.boss from user u  where u.user_id = ?2) and r.created_by =?2)", 
    nativeQuery=true)

    public Iterable<Role> findAllById(Long org_id,Long created_by );


    @Query("from Users1 u where u.user_id=?2 and u.org_id = ?1")
    public Users1 findUserbyOrgId(Long org_id, Long created_by);

}

ролей. Класс контроллера:

public ResponseEntity<Iterable<Role>> getAllRoles(@RequestParam("org_id") Long org_id, 
@RequestParam("created_by") Long created_by ) throws Exception {

        if( null != rolesRepository.findUserbyOrg(org_id, created_by)) {
            Iterable<Role> Roles = rolesRepository.findAllById(org_id, created_by); }

GET Response from postman:
[
    {
        "roleId": 3,
        "org_id": 2,
        "roleName": "manager",
        "createdBy": 5,
        "createdOn": 1591716178419,
    }
]

Я получаю все, кроме имени. Я не уверен, как получить это в моем GET API. Любая помощь будет очень признательна.

1 Ответ

0 голосов
/ 17 июня 2020

Не прямой ответ на ваш вопрос , но @ManyToMany обычно не приветствуется в реальном поле по следующим причинам.

  • В объединяющей таблице может потребоваться дополнительная информация (но не может)
  • Поскольку объединяющая таблица скрыта, результат запроса трудно предвидеть.

Рекомендуемый подход:

  • разложить два класса @ManyToMany на два класса @OneToMany + один класс @ManyToOne (объединяющая таблица)
  • поднять объединяемую таблицу до класса сущности.

Есть много таких практик кейсы в stackoverflow и youtube. Я думаю, что в конечном итоге вы сэкономите больше времени, если переключитесь на этот подход.

...