英文:
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<CryptoCount> 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<CryptoCount> 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<CryptoCount> findAllByCryptoWalletWalletOwnerId(UUID id);
我会得到两个数据库查询,而不是一个。我的代码有什么问题?
英文:
I have a chain of entities User -> CryptoWallet -> List<CryptoCount>
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;
}
2.
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<CryptoCount> cryptoCounts;
@OneToOne(mappedBy = "cryptoWallet")
private User walletOwner;
}
3.
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;
}
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 = {"cryptoCurrency","cryptoWallet","cryptoWallet.walletOwner"})
List<CryptoCount> findAllByCryptoWalletWalletOwnerId(UUID id);
BUT
When I annotate CryptoCount like this:
@NamedEntityGraph(name = "CryptoCountWithCurrencyAndWallet",attributeNodes = {
@NamedAttributeNode(value = "cryptoCurrency"),
@NamedAttributeNode(value = "cryptoWallet")
})
And CryptoWallet like this:
@NamedEntityGraph(name = "WalletWithCryptoCountsAndWalletOwner", attributeNodes = {
@NamedAttributeNode(value = "cryptoCounts"),
@NamedAttributeNode(value = "walletOwner",subgraph = "UserWithWallet")
}, subgraphs = {
@NamedSubgraph(name = "UserWithWallet", attributeNodes = @NamedAttributeNode("cryptoWallet"))
})
And also User like this:
@NamedEntityGraph(name = "UserWithWallet",attributeNodes = {
@NamedAttributeNode("cryptoWallet")
},subgraphs = {
@NamedSubgraph(name = "userWithWallet", attributeNodes = {@NamedAttributeNode("cryptoWallet")})
})
And also use next method in Repository:
@EntityGraph(value = "CryptoCountWithCurrencyAndWallet")
List<CryptoCount> 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 = "CryptoCountWithCurrencyAndWallet",attributeNodes = {
@NamedAttributeNode(value = "cryptoCurrency"),
@NamedAttributeNode(value = "cryptoWallet",subgraph = "withWalletOwner")
},subgraphs = {
@NamedSubgraph(name = "withWalletOwner",attributeNodes = {@NamedAttributeNode("walletOwner")})
})
In CryptoCount solved the problem
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论