Issue
I'm new to hibernate and started to try a little bit around. Now I have a problem with duplicates when I try to get "Sub categories" from the Apache Derby DB.
My structure:
Category
|__Sub category(s)
.....|__Product(s)
My problem:
When I try to get the "sub categories" I get the right ones, but they are duplicated. (See below [children]). What I want is just one of the sub categories.
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
What I think the problem is:
I think that it has something to do with the @OneToMany annotation and the resulting join table. Because I have 9 "products" which are subordinated to the same "sub category". Unfortunately I have no clue what I did wrong in my code that this happens.
I thought about filter the duplicates after I get them out of the database. But it doesn’t feel right. I would really appreciate if someone can explain me the mistake and the best practice for that!
Code:
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;
...
Database tables with data
Join table of categories and products:
Solution
Solution
If found a solution by myself. I have to use a query instead of find. But I still not understand why that happened. If someone could explain this behavior I would be thankful for that!
WORKING - 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;
}
}
...
Answered By - Mavelouscello