Entity Graph在Entity层不起作用,但在Repository层起作用。

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

Entity Graph does not work in Entity Layer but work in Repository Layer

问题

我有一个实体链 User -> CryptoWallet -> List<CryptoCount>

  1. ```java
  2. public class User {
  3. @Id
  4. @Column(name = "id")
  5. @GenericGenerator(name = "uuidFromIp" , strategy = "org.hibernate.id.uuid.CustomVersionOneStrategy")
  6. @GeneratedValue(generator = "uuid_gen_strategy")
  7. private UUID id;
  8. @Column(name = "user_name")
  9. private String userName;
  10. @Column(name = "email")
  11. private String email;
  12. @OneToOne(cascade = CascadeType.ALL)
  13. @JoinColumn(name = "crypto_wallet_id")
  14. private CryptoWallet cryptoWallet;
  15. }
  16. ```
  1. ```java
  2. public class CryptoWallet {
  3. @Id
  4. @Column(name = "id")
  5. @GeneratedValue(strategy = GenerationType.IDENTITY)
  6. private Long id;
  7. @Column(name = "balance")
  8. private BigDecimal balance;
  9. @OneToMany(mappedBy = "cryptoWallet", cascade = CascadeType.ALL)
  10. private List&lt;CryptoCount&gt; cryptoCounts;
  11. @OneToOne(mappedBy = "cryptoWallet")
  12. private User walletOwner;
  13. }
  14. ```
  1. ```java
  2. public class CryptoCount {
  3. @Id
  4. @Column(name = "id")
  5. @GeneratedValue(strategy = GenerationType.IDENTITY)
  6. private Long id;
  7. @ManyToOne
  8. @JoinColumn(name = "crypto_id")
  9. private CryptoCurrency cryptoCurrency;
  10. @Column(name = "count")
  11. private BigDecimal countOfCrypto;
  12. @ManyToOne
  13. @JoinColumn(name = "crypto_wallet_id")
  14. private CryptoWallet cryptoWallet;
  15. }
  16. ```

我的任务是以一次请求加载 CryptoWalletOwnerId 所有的 CryptoCount

当我在 Repository 层使用以下方法时,一切都正常工作(只有一个查询)。

  1. @EntityGraph(attributePaths = {"cryptoCurrency","cryptoWallet","cryptoWallet.walletOwner"})
  2. List&lt;CryptoCount&gt; findAllByCryptoWalletWalletOwnerId(UUID id);

但是

当我像这样注释 CryptoCount

  1. @NamedEntityGraph(name = "CryptoCountWithCurrencyAndWallet",attributeNodes = {
  2. @NamedAttributeNode(value = "cryptoCurrency"),
  3. @NamedAttributeNode(value = "cryptoWallet")
  4. })

以及像这样注释 CryptoWallet

  1. @NamedEntityGraph(name = "WalletWithCryptoCountsAndWalletOwner", attributeNodes = {
  2. @NamedAttributeNode(value = "cryptoCounts"),
  3. @NamedAttributeNode(value = "walletOwner",subgraph = "UserWithWallet")
  4. }, subgraphs = {
  5. @NamedSubgraph(name = "UserWithWallet", attributeNodes = @NamedAttributeNode("cryptoWallet"))
  6. })

还有像这样注释 User

  1. @NamedEntityGraph(name = "UserWithWallet",attributeNodes = {
  2. @NamedAttributeNode("cryptoWallet")
  3. },subgraphs = {
  4. @NamedSubgraph(name = "userWithWallet", attributeNodes = {@NamedAttributeNode("cryptoWallet")})
  5. })

并且在 Repository 中使用以下方法:

  1. @EntityGraph(value = "CryptoCountWithCurrencyAndWallet")
  2. List&lt;CryptoCount&gt; findAllByCryptoWalletWalletOwnerId(UUID id);

我会得到两个数据库查询,而不是一个。我的代码有什么问题?

英文:

I have a chain of entities User -> CryptoWallet -> List<CryptoCount>

  1. public class User {
  2. @Id
  3. @Column(name = &quot;id&quot;)
  4. @GenericGenerator(name = &quot;uuidFromIp&quot; , strategy = &quot;org.hibernate.id.uuid.CustomVersionOneStrategy&quot;)
  5. @GeneratedValue(generator = &quot;uuid_gen_strategy&quot;)
  6. private UUID id;
  7. @Column(name = &quot;user_name&quot;)
  8. private String userName;
  9. @Column(name = &quot;email&quot;)
  10. private String email;
  11. @OneToOne(cascade = CascadeType.ALL)
  12. @JoinColumn(name = &quot;crypto_wallet_id&quot;)
  13. private CryptoWallet cryptoWallet;
  14. }

2.

  1. public class CryptoWallet {
  2. @Id
  3. @Column(name = &quot;id&quot;)
  4. @GeneratedValue(strategy = GenerationType.IDENTITY)
  5. private Long id;
  6. @Column(name = &quot;balance&quot;)
  7. private BigDecimal balance;
  8. @OneToMany(mappedBy = &quot;cryptoWallet&quot;, cascade = CascadeType.ALL)
  9. private List&lt;CryptoCount&gt; cryptoCounts;
  10. @OneToOne(mappedBy = &quot;cryptoWallet&quot;)
  11. private User walletOwner;
  12. }

3.

  1. public class CryptoCount {
  2. @Id
  3. @Column(name = &quot;id&quot;)
  4. @GeneratedValue(strategy = GenerationType.IDENTITY)
  5. private Long id;
  6. @ManyToOne
  7. @JoinColumn(name = &quot;crypto_id&quot;)
  8. private CryptoCurrency cryptoCurrency;
  9. @Column(name = &quot;count&quot;)
  10. private BigDecimal countOfCrypto;
  11. @ManyToOne
  12. @JoinColumn(name = &quot;crypto_wallet_id&quot;)
  13. private CryptoWallet cryptoWallet;
  14. }

My task is to load All CryptoCount By CryptoWalletOwnerId in one request

When i use next method in Repository Layer everything work correctly(with one query).

  1. @EntityGraph(attributePaths = {&quot;cryptoCurrency&quot;,&quot;cryptoWallet&quot;,&quot;cryptoWallet.walletOwner&quot;})
  2. List&lt;CryptoCount&gt; findAllByCryptoWalletWalletOwnerId(UUID id);

BUT

When I annotate CryptoCount like this:

  1. @NamedEntityGraph(name = &quot;CryptoCountWithCurrencyAndWallet&quot;,attributeNodes = {
  2. @NamedAttributeNode(value = &quot;cryptoCurrency&quot;),
  3. @NamedAttributeNode(value = &quot;cryptoWallet&quot;)
  4. })

And CryptoWallet like this:

  1. @NamedEntityGraph(name = &quot;WalletWithCryptoCountsAndWalletOwner&quot;, attributeNodes = {
  2. @NamedAttributeNode(value = &quot;cryptoCounts&quot;),
  3. @NamedAttributeNode(value = &quot;walletOwner&quot;,subgraph = &quot;UserWithWallet&quot;)
  4. }, subgraphs = {
  5. @NamedSubgraph(name = &quot;UserWithWallet&quot;, attributeNodes = @NamedAttributeNode(&quot;cryptoWallet&quot;))
  6. })

And also User like this:

  1. @NamedEntityGraph(name = &quot;UserWithWallet&quot;,attributeNodes = {
  2. @NamedAttributeNode(&quot;cryptoWallet&quot;)
  3. },subgraphs = {
  4. @NamedSubgraph(name = &quot;userWithWallet&quot;, attributeNodes = {@NamedAttributeNode(&quot;cryptoWallet&quot;)})
  5. })

And also use next method in Repository:

  1. @EntityGraph(value = &quot;CryptoCountWithCurrencyAndWallet&quot;)
  2. List&lt;CryptoCount&gt; findAllByCryptoWalletWalletOwnerId(UUID id);

I get two database queries instead of one. Whats wrong with my code?

答案1

得分: 0

@NamedEntityGraph(name = "CryptoCountWithCurrencyAndWallet", attributeNodes = {
@NamedAttributeNode(value = "cryptoCurrency"),
@NamedAttributeNode(value = "cryptoWallet", subgraph = "withWalletOwner")
}, subgraphs = {
@NamedSubgraph(name = "withWalletOwner", attributeNodes = {@NamedAttributeNode("walletOwner")})
})

CryptoCount 中解决了这个问题。

英文:
  1. @NamedEntityGraph(name = &quot;CryptoCountWithCurrencyAndWallet&quot;,attributeNodes = {
  2. @NamedAttributeNode(value = &quot;cryptoCurrency&quot;),
  3. @NamedAttributeNode(value = &quot;cryptoWallet&quot;,subgraph = &quot;withWalletOwner&quot;)
  4. },subgraphs = {
  5. @NamedSubgraph(name = &quot;withWalletOwner&quot;,attributeNodes = {@NamedAttributeNode(&quot;walletOwner&quot;)})
  6. })

In CryptoCount solved the problem

huangapple
  • 本文由 发表于 2023年2月24日 11:20:58
  • 转载请务必保留本文链接:https://go.coder-hub.com/75552333.html
匿名

发表评论

匿名网友

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

确定