如何在JPA实体中使用其他字段的大小来初始化字段。

huangapple go评论80阅读模式
英文:

How to initialize fields with size others fields in entity JPA

问题

我有一个示例的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字段,使其具有users字段的大小值,而users字段是一个惰性加载字段?

我知道这是一个愚蠢的问题,但我找不到一个好的解决策略来解决这个问题。

我尝试了这个解决方案,但没有成功:

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 您的SQL语法有误;
请检查与您的MariaDB服务器版本对应的手册,以获取有关正确的语法使用方法,位于
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
未处理的异常:org.springframework.dao.InvalidDataAccessResourceUsageException:
无法提取ResultSet;SQL [n/a];嵌套异常是
org.hibernate.exception.SQLGrammarException:无法提取ResultSet

编辑 2:

我解决了这个问题。Ady Junior给了我一个很好的解决方案,错误是由于我愚蠢引起的。在@Formula("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 JuniorChristian Beikov

英文:

I have a example JPA entity:

@Entity
@Table(name = &quot;tb_group&quot;)
public class Group
{
  ...

   @ManyToMany
   @JoinTable(name = &quot;tb_group_user&quot;,
           joinColumns = @JoinColumn(name = &quot;fk_group_id&quot;, referencedColumnName = &quot;id&quot;),
           inverseJoinColumns = @JoinColumn(name = &quot;fk_user_id&quot;, referencedColumnName = &quot;id&quot;))
   private List&lt;User&gt; users;

   private Integer userSize;
   ...
}

My question is, how can i initialize userSize field, with the size value of users field,that is a Lazy Load field?

I know its a dumb question, but i can't find a good strategy to solve this problem.

I tried this solution, but haven't succeed:

private Integer userSize = users.size();

I'm confused with this problem. Can you help me with an example?

EDIT:

I tried solution @Formula(&quot;select count(gu.fk_user_id) from tb_group_user gu where gu.fk_group_id = id&quot;) suggested by Ady Junior, but i receive this exceptions, when i try get groups:

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

EDIT 2:

I got it solved the problem. Ady Junior give me a good solution, and the error was due to my stupidity. Inside @Formule(&quot;select count(gu.fk_user_id) from tb_group_user gu where gu.fk_group_id = id&quot;) i forgot putied parentheses '(' ')' between query.

The correct solution for my problem this:

 @Entity
 @Table(name = &quot;tb_group&quot;)
 public class Group
 {
   ...

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

Thanks Ady Junior and Thanks Christian Beikov

答案1

得分: 1

你可以使用@LazyCollection(LazyCollectionOption.EXTRA)来使用额外延迟加载集合,但我不建议这样做:https://vladmihalcea.com/hibernate-extra-lazy-collections/

Ady Junior提出的方法,即使用@Formula(&quot;select count(gu.fk_user_id) from tb_group_user gu where gu.fk_group_id = id&quot;),是一个可行的方法,但可能更好的是使用DTO查询,在加载数据的查询中确定大小。类似这样的方式:

entityManager.createQuery(&quot;SELECT g.name, SIZE(g.users) FROM Group g&quot;)

英文:

You could use extra-lazy collections with @LazyCollection(LazyCollectionOption.EXTRA) but I wouldn't recommend that: https://vladmihalcea.com/hibernate-extra-lazy-collections/

The approach Ady Junior proposed i.e. to use @Formula(&quot;select count(gu.fk_user_id) from tb_group_user gu where gu.fk_group_id = id&quot;) is a way you could go, but probably it's better to use a DTO query and determine the size in the query you use to load the data. Something like this

entityManager.createQuery(&quot;SELECT g.name, SIZE(g.users) FROM Group g&quot;)

答案2

得分: 1

devsaleh,请尝试使用 @Formula 注解编写一个计数查询。

关于这个注解有很多特性。例如,在这篇由 Vlad Mihalcea 写的很棒的文章中:[https://vladmihalcea.com/how-to-map-calculated-properties-with-jpa-and-hibernate-formula-annotation/][1]

@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;
   
   ...
}

[1]: https://vladmihalcea.com/how-to-map-calculated-properties-with-jpa-and-hibernate-formula-annotation/

@devsaleh,非常感谢!

最好的祝愿!
英文:

devsaleh, try use @Formula to write a count query.

There are many features about this annotation. For instance, in this awesome post written by Vlad Mihalcea: https://vladmihalcea.com/how-to-map-calculated-properties-with-jpa-and-hibernate-formula-annotation/

 @Entity
 @Table(name = &quot;tb_group&quot;)
 public class Group
 {
   ...

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

@devsaleh, Thank you very much!

Best Regards!

huangapple
  • 本文由 发表于 2020年5月5日 01:20:11
  • 转载请务必保留本文链接:https://go.coder-hub.com/61597978.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定