У меня есть проект JAVA / JPA (реализованный Hibernate). Базовое приложение было сгенерировано с помощью JHIPSTER (затем я настроил его), это отношения:
entity Competence {
description String required maxlength(200),
}
entity UserCompetenceLevel (user_comp_le) {
level Integer required
}
relationship ManyToOne {
UserCompetenceLevel {competence (description)} to Competence,
UserCompetenceLevel {user (login)} to User
}
Возможно, что у пользователя есть некоторые компетенции, но не все компетенции: я хочу, чтобы, когда я выбираю @GetMapping("/user-competence-levels")
Я получаю список всех UserCompetenceLevel
, а также «еще не существует» UserCompetenceLevel
. Для того проекта, который был определен до того, как он пришел ко мне, я должен использовать внешнее соединение. Hibernate не поддерживает правое соединение, поэтому мне пришлось использовать левое соединение.
Я мог сделать это, работая в @GetMapping("/user-competence-levels")
, используя findAllOuterJoinWorking()
; в этом ресурсе я выбираю Competence
в левом соединении с UserCompetenceLevel
как Object[]
. Затем я перебираю результат, как вы можете видеть в коде, создавая список UserCompetenceLevel
для возврата. Это пример возвращаемого UserCompetenceLevel, когда никого нет для компетенции 13:
{
"id": null,
"level": null,
"competence": {
"id": 13,
"description": "react"
},
"user": null
}
Я также сделал ресурс @GetMapping("/user-competence-levels-2nw")
, используя List<UserCompetenceLevel> findAllOuterJoin2NotWorking()
; Я бы хотел использовать этот способ, но он работает не так, как findAllOuterJoinWorking
. Для компетенции 13 я просто получаю null
. Можете ли вы помочь мне изменить getAllUserCompetenceLevels()
+ findAllOuterJoinWorking
, чтобы они работали как getAllUserCompetenceLevelsNW()
+ findAllOuterJoin2NotWorking
+?
Другими словами: мне нужна ваша помощь, чтобы изменить findAllOuterJoin2NotWorking
, чтобы он не возвращает список массивов объектов, но список UserCompetenceLevel
. Мне не нравится приведенная ниже итерация в списке массивов объектов (for (Object[] one : joinList) {....
): мне бы хотелось, чтобы hibernate возвращал непосредственно UserCompetenceLevel
, правильно внешний соединенный с Competence
.
весь соответствующий код:
@Repository
public interface UserCompetenceLevelRepository extends JpaRepository<UserCompetenceLevel, Long> {
@Query("select u, c from Competence c LEFT JOIN UserCompetenceLevel u on u.competence.id=c.id")
public List<Object[]> findAllOuterJoinWorking();
@Query("select u from Competence c LEFT JOIN FETCH UserCompetenceLevel u on u.competence.id=c.id")
List<UserCompetenceLevel> findAllOuterJoin2NotWorking();
}
@RestController
@RequestMapping("/api")
@Transactional
public class UserCompetenceLevelResource {
@GetMapping("/user-competence-levels")
public List<UserCompetenceLevel> getAllUserCompetenceLevels() {
//working
List<Object[]> joinList=userCompetenceLevelRepository.findAllOuterJoinWorking();
ArrayList<UserCompetenceLevel> returned= new ArrayList<UserCompetenceLevel>();
for (Object[] one : joinList) {
if (one[0] == null) {
UserCompetenceLevel missingUCL = new UserCompetenceLevel();
Competence missingCompetence = (Competence) one[1];
missingUCL.setCompetence(missingCompetence);
returned.add(missingUCL);
} else {
UserCompetenceLevel present = (UserCompetenceLevel) one[0];
returned.add(present);
}
}
return returned;
}
@GetMapping("/user-competence-levels-2nw")
public List<UserCompetenceLevel> getAllUserCompetenceLevelsNW() {
//not working
return userCompetenceLevelRepository.findAllOuterJoin2NotWorking();
}
}
@Entity
@Table(name = "user_comp_le")
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class UserCompetenceLevel implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@NotNull
@Column(name = "level", nullable = false)
private Integer level;
@ManyToOne
@JsonIgnoreProperties("userCompetenceLevels")
private Competence competence;
@ManyToOne
@JsonIgnoreProperties("userCompetenceLevels")
private User user;
(...)
}