Как сопоставить результирующий набор собственного запроса с переменной в сущности
У меня есть две сущности: пользователи и аннотации, и я хочу добавить набор результатов из запроса к таблице аннотаций к временной переменной в сущности "Пользователи".
Объекты:
пользователей
@Entity
public class Users {
@Id
@GeneratedValue
@Column(name="user_id")
private Long userId;
@Column(name="username", unique=true, nullable=false)
private String username;
@Transient
private Set<Annotation> annotations;
.....
Аннотации
@Entity
@Table(name="Annotation")
public class Annotation {
@Id
@GeneratedValue
@Column(name="anno_id")
private Long annoId;
@Column(name="user_id", nullable=false)
private Long userId;
@Enumerated(EnumType.STRING)
@Column(name="access_control", nullable=false)
private Access accessControl;
@Column(name="group_id", nullable=true)
private Long groupId;
.....
Итак, я хочу Set<Annotation> annotations
переменная для хранения результатов запроса в таблице аннотаций. Это не может быть просто отображение один-ко-многим, потому что я должен ограничивать результаты определенным образом. На самом деле, запрос таков:
SELECT anno_id, a.user_id, timestamp, is_redacted, access_control, a.group_id, vocabulary_id, key_, value, target_type, target_id, root_type, root_id FROM Annotation AS a
LEFT JOIN group_membership g ON g.user_id = ?#{ principal?.getId() }
WHERE a.user_id = :id
AND (a.access_control='PUBLIC'
OR (a.access_control='GROUP' AND a.group_id = g.group_id
OR (a.access_control='PRIVATE' AND g.user_id = a.user_id))
GROUP BY a.anno_id
Я думаю, что это возможно с помощью SQLResultSetMapping, однако, кажется, что результаты всегда отображаются в другую, отдельную сущность. Можно ли извлечь набор как коллекцию и сохранить его так, как я хочу?
1 ответ
Вы не можете использовать SQLResultSetMapping в этом сценарии, так как результаты будут отображаться только как отдельные объекты. Что вы можете сделать, это выполнить как собственный запрос, а затем получить результат в виде списка массивов объектов. Затем вы можете построить нужный вам объект.
Query query = entityManager
.createNativeQuery("SELECT anno_id, a.user_id FROM Annotation AS a"
+ " LEFT JOIN group_membership g ON g.user_id = ?"
+ " WHERE a.user_id = ?"
+ " AND (a.access_control='PUBLIC'"
+ " OR (a.access_control='GROUP' AND a.group_id = g.group_id)"
+ " OR (a.access_control='PRIVATE' AND g.user_id = a.user_id))"
+ " GROUP BY a.anno_id");
query.setParameter(1, new Long(1));
query.setParameter(2, new Long(1));
List<Object[]> list = query.getResultList();
return list;