I am designing a product catalogue. I would like to have a category tree, where products can be connected only to LeafCategories, that can have one parent Category. I am using Spring Boot, Spring Data and Hibernate 4 and H2 database(for now).
Base entity for the task is AbstractCategory (Is it there a better way to inherit relationships ?) (Getters and Setters omitted, NamedEntity is a @MappedSuperclass with String name and Long id)
public abstract class AbstractCategory extends NamedEntity{
@ManyToOne(cascade = CascadeType.PERSIST)
@JoinColumn(name = "parentId")
Category parent;
}
Category entities - they are not leafs and cannot have Products connected to them:
@Entity
public class Category extends AbstractCategory {
@OneToMany(cascade = CascadeType.ALL, mappedBy = "parent")
Collection<AbstractCategory> subcategories;
}
LeafCategory it can be used as a property for my Product entity.
@Entity
public class LeafCategory extends AbstractCategory {
@OneToMany(cascade = CascadeType.PERSIST, mappedBy = "category")
Collection<Product> products;
}
I have a very simple CrudRepository for Category and an identical for LeafCategory
@Repository
@Transactional
public interface CategoryRepository extends CrudRepository<Category, Long> {}
When I load a Category from CategoryRepository and access getSubcategories() I get following exception:
Caused by: org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: uj.jg.domain.products.Category.subcategories, could not initialize proxy - no Session
First of all - How can I improve the design? Second and more concrete question is why is @Transactional
not keeping a session open? I know I could just use FetchType.EAGER
, but it's a recursive structure - if my understanding of Hibernate is correct it would mean loading the whole subtree, and I don't want that. I don't want to use Hibernate.initialize
either.
I do not have any config for database or hibernate. I am using devtools from spring.boot:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>