Hibernate:从@OneToMany 关系中获取重复项
Hibernate: Get duplicates as result out of @OneToMany relationship
我是休眠新手,开始尝试一下。现在,当我尝试从 Apache Derby DB 获取“子类别”时,我遇到了重复问题。
我的结构:
Category
|__Sub category(s)
.....|__Product(s)
我的问题:
当我尝试获取“子类别”时,我得到了正确的,但它们是重复的。 (见下文[儿童])。我要的只是其中一个子类
children: Array(9)
0: {description: 'A place to collect your single malts.', id: 101, name: 'Single Malt', status: 'verified'}
1: {description: 'A place to collect your single malts.', id: 101, name: 'Single Malt', status: 'verified'}
2: {description: 'A place to collect your single malts.', id: 101, name: 'Single Malt', status: 'verified'}
3: {description: 'A place to collect your single malts.', id: 101, name: 'Single Malt', status: 'verified'}
4: {description: 'A place to collect your single malts.', id: 101, name: 'Single Malt', status: 'verified'}
5: {description: 'A place to collect your single malts.', id: 101, name: 'Single Malt', status: 'verified'}
6: {description: 'A place to collect your single malts.', id: 101, name: 'Single Malt', status: 'verified'}
7: {description: 'A place to collect your single malts.', id: 101, name: 'Single Malt', status: 'verified'}
8: {description: 'A place to collect your single malts.', id: 101, name: 'Single Malt', status: 'verified'}
length: 9
[[Prototype]]: Array(0)
description: "A place to collect your whiskies."
id: 100
name: "Whisky"
products: []
status: "verified"
[[Prototype]]: Object
我认为问题是:
我认为它与@OneToMany 注释和生成的连接有关table。因为我有 9 个“产品”属于同一个“子类别”。不幸的是,我不知道我的代码做错了什么会发生这种情况。
我想在从数据库中取出重复项后对其进行过滤。但感觉不对。如果有人能向我解释错误和最佳做法,我将不胜感激!
代码:
CategoryRepository.java
@RequestScoped
@Transactional(value = Transactional.TxType.REQUIRED,
dontRollbackOn = {SqlException.class},
rollbackOn = {SecurityException.class})
public class CategoryRepository implements CategoryCatalog {
@Inject
protected EntityManager em;
...
@Override
public Category getCategory(Long id) {
if (id == null) {
return null;
}
try {
Category category = this.em.find(Category.class, id);
if(category != null){
category.setProducts(this.filterFlaggedOrHiddenUserProducts(category.getProducts()));
}
return category;
} catch (IllegalArgumentException ex){
return null;
}
}
...
Category.java
@Entity(name = "CATEGORIES")
public class Category implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "CATEGORY_ID")
private Long id;
@ManyToOne
private Category parentCategory;
@OneToMany(mappedBy = "parentCategory", cascade = { CascadeType.PERSIST, CascadeType.MERGE}, fetch = FetchType.EAGER)
private List<Category> children;
@OneToMany(cascade = { CascadeType.PERSIST, CascadeType.MERGE}, fetch = FetchType.EAGER)
private List<Product> products;
@NotNull
@Column(name = "CATEGORY_NAME")
private String name;
...
数据库 tables 有数据
Table 个类别:
加入 table 个类别和产品:
解决方案
如果自己找到解决办法。我必须使用查询而不是查找。但我仍然不明白为什么会这样。如果有人能解释这种行为,我将不胜感激!
正在工作 - CategoryRepository.java
@RequestScoped
@Transactional(value = Transactional.TxType.REQUIRED,
dontRollbackOn = {SqlException.class},
rollbackOn = {SecurityException.class})
public class CategoryRepository implements CategoryCatalog {
@Inject
protected EntityManager em;
...
@Override
public Category getCategory(Long id) {
if (id == null) {
return null;
}
try {
Category category = this.em.createQuery("select c from CATEGORIES c WHERE CATEGORY_ID IS " + id, Category.class).getSingleResult();
if(category != null){
category.setProducts(this.filterFlaggedOrHiddenUserProducts(category.getProducts()));
}
return category;
} catch (IllegalArgumentException ex){
return null;
}
}
...
我是休眠新手,开始尝试一下。现在,当我尝试从 Apache Derby DB 获取“子类别”时,我遇到了重复问题。
我的结构:
Category
|__Sub category(s)
.....|__Product(s)
我的问题:
当我尝试获取“子类别”时,我得到了正确的,但它们是重复的。 (见下文[儿童])。我要的只是其中一个子类
children: Array(9)
0: {description: 'A place to collect your single malts.', id: 101, name: 'Single Malt', status: 'verified'}
1: {description: 'A place to collect your single malts.', id: 101, name: 'Single Malt', status: 'verified'}
2: {description: 'A place to collect your single malts.', id: 101, name: 'Single Malt', status: 'verified'}
3: {description: 'A place to collect your single malts.', id: 101, name: 'Single Malt', status: 'verified'}
4: {description: 'A place to collect your single malts.', id: 101, name: 'Single Malt', status: 'verified'}
5: {description: 'A place to collect your single malts.', id: 101, name: 'Single Malt', status: 'verified'}
6: {description: 'A place to collect your single malts.', id: 101, name: 'Single Malt', status: 'verified'}
7: {description: 'A place to collect your single malts.', id: 101, name: 'Single Malt', status: 'verified'}
8: {description: 'A place to collect your single malts.', id: 101, name: 'Single Malt', status: 'verified'}
length: 9
[[Prototype]]: Array(0)
description: "A place to collect your whiskies."
id: 100
name: "Whisky"
products: []
status: "verified"
[[Prototype]]: Object
我认为问题是:
我认为它与@OneToMany 注释和生成的连接有关table。因为我有 9 个“产品”属于同一个“子类别”。不幸的是,我不知道我的代码做错了什么会发生这种情况。
我想在从数据库中取出重复项后对其进行过滤。但感觉不对。如果有人能向我解释错误和最佳做法,我将不胜感激!
代码:
CategoryRepository.java
@RequestScoped
@Transactional(value = Transactional.TxType.REQUIRED,
dontRollbackOn = {SqlException.class},
rollbackOn = {SecurityException.class})
public class CategoryRepository implements CategoryCatalog {
@Inject
protected EntityManager em;
...
@Override
public Category getCategory(Long id) {
if (id == null) {
return null;
}
try {
Category category = this.em.find(Category.class, id);
if(category != null){
category.setProducts(this.filterFlaggedOrHiddenUserProducts(category.getProducts()));
}
return category;
} catch (IllegalArgumentException ex){
return null;
}
}
...
Category.java
@Entity(name = "CATEGORIES")
public class Category implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "CATEGORY_ID")
private Long id;
@ManyToOne
private Category parentCategory;
@OneToMany(mappedBy = "parentCategory", cascade = { CascadeType.PERSIST, CascadeType.MERGE}, fetch = FetchType.EAGER)
private List<Category> children;
@OneToMany(cascade = { CascadeType.PERSIST, CascadeType.MERGE}, fetch = FetchType.EAGER)
private List<Product> products;
@NotNull
@Column(name = "CATEGORY_NAME")
private String name;
...
数据库 tables 有数据
Table 个类别:
加入 table 个类别和产品:
解决方案
如果自己找到解决办法。我必须使用查询而不是查找。但我仍然不明白为什么会这样。如果有人能解释这种行为,我将不胜感激!
正在工作 - CategoryRepository.java
@RequestScoped
@Transactional(value = Transactional.TxType.REQUIRED,
dontRollbackOn = {SqlException.class},
rollbackOn = {SecurityException.class})
public class CategoryRepository implements CategoryCatalog {
@Inject
protected EntityManager em;
...
@Override
public Category getCategory(Long id) {
if (id == null) {
return null;
}
try {
Category category = this.em.createQuery("select c from CATEGORIES c WHERE CATEGORY_ID IS " + id, Category.class).getSingleResult();
if(category != null){
category.setProducts(this.filterFlaggedOrHiddenUserProducts(category.getProducts()));
}
return category;
} catch (IllegalArgumentException ex){
return null;
}
}
...