spring - How to design JPA polymorphic relationships in java? -


i designing product catalogue. have category tree, products can connected leafcategories, can have 1 parent category. using spring boot, spring data , hibernate 4 , h2 database(for now).

base entity task abstractcategory (is there better way inherit relationships ?) (getters , setters omitted, namedentity @mappedsuperclass string name , long id)

public abstract class abstractcategory extends namedentity{     @manytoone(cascade = cascadetype.persist)     @joincolumn(name = "parentid")     category parent; } 

category entities - not leafs , cannot have products connected them:

@entity public class category extends abstractcategory {      @onetomany(cascade = cascadetype.all, mappedby = "parent")     collection<abstractcategory> subcategories; } 

leafcategory can used property product entity.

@entity public class leafcategory extends abstractcategory {     @onetomany(cascade = cascadetype.persist, mappedby = "category")     collection<product> products; } 

i have simple crudrepository category , identical leafcategory

@repository @transactional public interface categoryrepository extends crudrepository<category, long> {} 

when load category categoryrepository , access getsubcategories() following exception:

caused by: org.hibernate.lazyinitializationexception: failed lazily initialize collection of role: uj.jg.domain.products.category.subcategories,  not initialize proxy - no session 

first of - how can improve design? second , more concrete question why @transactional not keeping session open? know use fetchtype.eager, it's recursive structure - if understanding of hibernate correct mean loading whole subtree, , don't want that. don't want use hibernate.initialize either.

i not have config database or hibernate. using devtools spring.boot:

<dependency>     <groupid>org.springframework.boot</groupid>     <artifactid>spring-boot-devtools</artifactid> </dependency> 

how can improve design?

it looks reasonable me.

why @transactional not keeping session open?

you have placed @transactional on repository. db session open time of running query, returns categories subcategories marked lazy-loaded. then, session closed (once repository method returns) , trying access subcategories after that, when there's no session more. move @transactional annotation higher call stack - service layer if using 3-layer architecture (cf. this post).

since repository methods run single query, there's no need mark them @transactional - run within transaction anyway. makes sense have @transactional when run several queries or run query , other processing (which throw exception , you'd want query rolled because of it). that's why, again, if want explicitly mark @transactional rather in service layer.


Comments

Popular posts from this blog

sublimetext3 - what keyboard shortcut is to comment/uncomment for this script tag in sublime -

java - No use of nillable="0" in SOAP Webservice -

ubuntu - Laravel 5.2 quickstart guide gives Not Found Error -