使用@Any(fetch = FetchType.EAGER)和Spring-boot进行LazyInitializationException

时间:2014-06-18 13:10:00

标签: java hibernate jpa spring-data-jpa

我遇到了一个常见的例外" org.hibernate.LazyInitializationException:无法初始化代理 - 没有会话"尽管" fetch = FetchType.EAGER "而且我不能(手动)手动管理hibernate会话(我使用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
}

Holder的存储库:

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。

出现打印点异常。我想我得到了org.hibernate.LazyInitializationException,因为fetch = FetchType.EAGER确实无效。

此外,级联仅适用于PERSIST。 也许混合Hibernate和JPA的问题,但我无法处理它。 提前致谢!

1 个答案:

答案 0 :(得分:0)

这不是好的解决方案,但它有效。但我想变得更好。 它是@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;
}

}