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

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

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

问题

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

```java
public class User {

    @Id
    @Column(name = "id")
    @GenericGenerator(name = "uuidFromIp" , strategy = "org.hibernate.id.uuid.CustomVersionOneStrategy")
    @GeneratedValue(generator = "uuid_gen_strategy")
    private UUID id;

    @Column(name = "user_name")
    private String userName;

    @Column(name = "email")
    private String email;

    @OneToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "crypto_wallet_id")
    private CryptoWallet cryptoWallet;
}
```
```java
public class CryptoWallet {
    @Id
    @Column(name = "id")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "balance")
    private BigDecimal balance;

    @OneToMany(mappedBy = "cryptoWallet", cascade = CascadeType.ALL)
    private List&lt;CryptoCount&gt; cryptoCounts;

    @OneToOne(mappedBy = "cryptoWallet")
    private User walletOwner;
}
```
```java
public class CryptoCount {

    @Id
    @Column(name = "id")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @ManyToOne
    @JoinColumn(name = "crypto_id")
    private CryptoCurrency cryptoCurrency;

    @Column(name = "count")
    private BigDecimal countOfCrypto;

    @ManyToOne
    @JoinColumn(name = "crypto_wallet_id")
    private CryptoWallet cryptoWallet;
}
```

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

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

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

但是

当我像这样注释 CryptoCount

@NamedEntityGraph(name = "CryptoCountWithCurrencyAndWallet",attributeNodes = {
    @NamedAttributeNode(value = "cryptoCurrency"),
    @NamedAttributeNode(value = "cryptoWallet")
})

以及像这样注释 CryptoWallet

@NamedEntityGraph(name = "WalletWithCryptoCountsAndWalletOwner", attributeNodes = {
    @NamedAttributeNode(value = "cryptoCounts"),
    @NamedAttributeNode(value = "walletOwner",subgraph = "UserWithWallet")
}, subgraphs = {
    @NamedSubgraph(name = "UserWithWallet", attributeNodes = @NamedAttributeNode("cryptoWallet"))
})

还有像这样注释 User

@NamedEntityGraph(name = "UserWithWallet",attributeNodes = {
    @NamedAttributeNode("cryptoWallet")
},subgraphs = {
    @NamedSubgraph(name = "userWithWallet", attributeNodes = {@NamedAttributeNode("cryptoWallet")})
})

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

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

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

英文:

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

public class User {

    @Id
    @Column(name = &quot;id&quot;)
    @GenericGenerator(name = &quot;uuidFromIp&quot; , strategy = &quot;org.hibernate.id.uuid.CustomVersionOneStrategy&quot;)
    @GeneratedValue(generator = &quot;uuid_gen_strategy&quot;)
    private UUID id;

    @Column(name = &quot;user_name&quot;)
    private String userName;

    @Column(name = &quot;email&quot;)
    private String email;

    @OneToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = &quot;crypto_wallet_id&quot;)
    private CryptoWallet cryptoWallet;
}

2.

public class CryptoWallet {
    @Id
    @Column(name = &quot;id&quot;)
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = &quot;balance&quot;)
    private BigDecimal balance;

    @OneToMany(mappedBy = &quot;cryptoWallet&quot;, cascade = CascadeType.ALL)
    private List&lt;CryptoCount&gt; cryptoCounts;

    @OneToOne(mappedBy = &quot;cryptoWallet&quot;)
    private User walletOwner;
}

3.

public class CryptoCount {

    @Id
    @Column(name = &quot;id&quot;)
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @ManyToOne
    @JoinColumn(name = &quot;crypto_id&quot;)
    private CryptoCurrency cryptoCurrency;

    @Column(name = &quot;count&quot;)
    private BigDecimal countOfCrypto;

    @ManyToOne
    @JoinColumn(name = &quot;crypto_wallet_id&quot;)
    private CryptoWallet cryptoWallet;
}

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).

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

BUT

When I annotate CryptoCount like this:

@NamedEntityGraph(name = &quot;CryptoCountWithCurrencyAndWallet&quot;,attributeNodes = {
        @NamedAttributeNode(value = &quot;cryptoCurrency&quot;),
        @NamedAttributeNode(value = &quot;cryptoWallet&quot;)
})

And CryptoWallet like this:

@NamedEntityGraph(name = &quot;WalletWithCryptoCountsAndWalletOwner&quot;, attributeNodes = {
        @NamedAttributeNode(value = &quot;cryptoCounts&quot;),
        @NamedAttributeNode(value = &quot;walletOwner&quot;,subgraph = &quot;UserWithWallet&quot;)
}, subgraphs = {
        @NamedSubgraph(name = &quot;UserWithWallet&quot;, attributeNodes = @NamedAttributeNode(&quot;cryptoWallet&quot;))
})

And also User like this:

@NamedEntityGraph(name = &quot;UserWithWallet&quot;,attributeNodes = {
        @NamedAttributeNode(&quot;cryptoWallet&quot;)
},subgraphs = {
        @NamedSubgraph(name = &quot;userWithWallet&quot;, attributeNodes = {@NamedAttributeNode(&quot;cryptoWallet&quot;)})
})

And also use next method in Repository:

@EntityGraph(value = &quot;CryptoCountWithCurrencyAndWallet&quot;)
    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 中解决了这个问题。

英文:
@NamedEntityGraph(name = &quot;CryptoCountWithCurrencyAndWallet&quot;,attributeNodes = {
        @NamedAttributeNode(value = &quot;cryptoCurrency&quot;),
        @NamedAttributeNode(value = &quot;cryptoWallet&quot;,subgraph = &quot;withWalletOwner&quot;)
},subgraphs = {
        @NamedSubgraph(name = &quot;withWalletOwner&quot;,attributeNodes = {@NamedAttributeNode(&quot;walletOwner&quot;)})
})

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:

确定