LazyInitializationException с @Any(выборка = FetchType.НЕТЕРПЕЛИВЫЙ) и Spring-boot

#java #hibernate #jpa #spring-data-jpa

#java #спящий режим #jpa #spring-data-jpa

Вопрос:

Я получил общее исключение «org.hibernate.LazyInitializationException: не удалось инициализировать прокси-сервер — нет сеанса «несмотря на «fetch = FetchType .НЕТЕРПЕЛИВЫЙ» и я не могу (не хочу) управлять сеансом гибернации вручную (я использую Spring-Boot-starter-data-jpa).

У меня есть объект Hilder, который содержит свойство CommonType (TapeA или TypeB):

   @Entity
public class Holder<T extends CommonType> {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;

@Any(metaColumn = @Column(name = "type", nullable = false), optional = false, fetch = FetchType.EAGER)
@Cascade(org.hibernate.annotations.CascadeType.ALL )
@AnyMetaDef(
        idType = "long",
        metaType = "string",
        metaValues = {
                @MetaValue(value = "TypeA", targetEntity = TypeB.class),
                @MetaValue(value = "TypeB", targetEntity = TypeA.class)
        })
@JoinColumn(name = "property_id", nullable = false)
private T type; 
 //getters and setters}
  

TypeB выглядит как TypeA:

 @Entity
public class TypeA implements CommonType {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;

    private double param=0;
//getters and setters
}
  

И репозиторий для держателя :

 import org.springframework.transaction.annotation.Transactional;

@Transactional
public interface HolderRepository extends CrudRepository<Holder, Long> {
}
  

Бегун:

 @Configuration
@EnableAutoConfiguration
public class Application {

    public static void main(String[] args) {
        ConfigurableApplicationContext context =       SpringApplication.run(Application.class);
    HolderRepository repository = context.getBean(HolderRepository.class);

    TypeA simpleDeviceState = new TypeA();
    Holder<TypeA> holder = new Holder<>(simpleDeviceState);
    repository.save(holder);

    Holder holder1=repository.findAll().iterator().next();
    TypeA typeA= (TypeA) holder1.getType();

    System.out.println("Param: " typeA.getParam());
    context.close();
}}
  

Pom содержит только org.springframework.boot::spring-boot-starter-data-jpa и com.h2database::h2. база данных::h2.

В точке печати появляется исключение. Я предполагаю, что я получаю org.hibernate.LazyInitializationException потому что fetch = FetchType .НЕТЕРПЕЛИВЫЙ не работает.

Также каскадирование работает только для сохранения. Возможно, проблема в смешивании гибернации и JPA, но я не могу с этим справиться. Заранее спасибо!

Ответ №1:

Это не очень хорошее решение, но оно работает. Но я хотел бы получить лучший вариант. Это сервис с @Transactional и Hibernate.initialize.инициализировать:

 @Component
@Transactional
public class ServiceHolder {

@Autowired
HolderRepository holderRepository;

public Holder getH(long id) {
    Holder holder = holderRepository.findOne(id);
    Hibernate.initialize(holder.getType());
    return holder;
}
  

}