Как инициализировать поля с размером других полей в сущности JPA - PullRequest
1 голос
/ 04 мая 2020

У меня есть пример сущности JPA:

@Entity
@Table(name = "tb_group")
public class Group
{
  ...

   @ManyToMany
   @JoinTable(name = "tb_group_user",
           joinColumns = @JoinColumn(name = "fk_group_id", referencedColumnName = "id"),
           inverseJoinColumns = @JoinColumn(name = "fk_user_id", referencedColumnName = "id"))
   private List<User> users;

   private Integer userSize;
   ...
}

Мой вопрос: как я могу инициализировать поле userSize значением поля user, которое является полем Lazy Load?

Я знаю, что это глупый вопрос, но я не могу найти хорошую стратегию для решения этой проблемы.

Я пробовал это решение, но не смог:

private Integer userSize = users.size();

Я запутался с этой проблемой. Можете ли вы помочь мне с примером?

РЕДАКТИРОВАТЬ:

Я пробовал решение @Formula("select count(gu.fk_user_id) from tb_group_user gu where gu.fk_group_id = id") предложено Ady Junior , но я получаю это исключения , когда я пытаюсь получить группы:

ERROR   org.hibernate.engine.jdbc.spi.SqlExceptionHelper You have an error in your SQL syntax; 
check the manual that corresponds to your MariaDB server version for the right syntax to use near 
select count(gu.fk_user_id) from tb_group_user gu where gu.fk_group_id = group

ERROR   br.com.loopec.loopkey.server.controller.ExceptionsHandler   
Unhandled Exception: org.springframework.dao.InvalidDataAccessResourceUsageException: could not extract ResultSet; SQL [n/a]; nested exception is 
org.hibernate.exception.SQLGrammarException: could not extract ResultSet

РЕДАКТИРОВАТЬ 2:

Я получил это решил проблему. Ady Junior дайте мне хорошее решение, и ошибка произошла из-за моей глупости. Внутри @Formule("select count(gu.fk_user_id) from tb_group_user gu where gu.fk_group_id = id") я забыл заключить в скобки круглые скобки '(' ')' между запросами.

Правильное решение моей проблемы это:

 @Entity
 @Table(name = "tb_group")
 public class Group
 {
   ...

   @ManyToMany
   @JoinTable(name = "tb_group_user",
           joinColumns = @JoinColumn(name = "fk_group_id", referencedColumnName = "id"),
           inverseJoinColumns = @JoinColumn(name = "fk_user_id", referencedColumnName = "id"))
   private List<User> users;
   @Formula("(select count(gu.fk_user_id) from tb_group_user gu where gu.fk_group_id = id)")
   private Integer userSize;
   ...
}

Спасибо Ady Junior и Спасибо Кристиан Бейков

Ответы [ 2 ]

0 голосов
/ 06 мая 2020

devsaleh, попробуйте использовать @Formula для написания запроса на подсчет.

В этой аннотации много функций. Например, в этом удивительном сообщении, написанном Владом Михалчеа: https://vladmihalcea.com/how-to-map-calculated-properties-with-jpa-and-hibernate-formula-annotation/

 @Entity
 @Table(name = "tb_group")
 public class Group
 {
   ...

   @ManyToMany
   @JoinTable(name = "tb_group_user",
           joinColumns = @JoinColumn(name = "fk_group_id", referencedColumnName = "id"),
           inverseJoinColumns = @JoinColumn(name = "fk_user_id", referencedColumnName = "id"))
   private List<User> users;
   @Formula("(select count(gu.fk_user_id) from tb_group_user gu where gu.fk_group_id = id)")
   private Integer userSize;
   ...
}

@ devsaleh, Большое спасибо!

С наилучшими пожеланиями!

0 голосов
/ 05 мая 2020

Вы можете использовать очень ленивые коллекции с @LazyCollection(LazyCollectionOption.EXTRA), но я бы не рекомендовал: https://vladmihalcea.com/hibernate-extra-lazy-collections/

Подход, предложенный Ady Junior, то есть использование @Formula("select count(gu.fk_user_id) from tb_group_user gu where gu.fk_group_id = id"), является как вы могли бы go, но, вероятно, лучше использовать запрос DTO и определить размер в запросе, который вы используете для загрузки данных. Как то так

entityManager.createQuery("SELECT g.name, SIZE(g.users) FROM Group g")

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...