Spring-data-jpa LazyInitializationException:没有Session

时间:2014-04-09 10:50:10

标签: java spring hibernate jpa spring-data-jpa

我遇到了Spring-data-jpa项目的问题。

JavaConfig文件

...

@Configuration
@EnableJpaRepositories("it.myproject.data")
@EnableTransactionManagement(mode = AdviceMode.ASPECTJ, proxyTargetClass = true)
@PropertySource("classpath:/it/myproject/application.properties")
public
        class DBConfig
{

    private static final
            String PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN = "entitymanager.packages.to.scan";
    @Resource
    private
            Environment environment;

    @Bean
    public
            DataSource dataSource()
    {
        EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder();
        return builder.setType(EmbeddedDatabaseType.H2).build();
    }

    @Bean
    public
            EntityManagerFactory entityManagerFactory()
    {
        HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
        vendorAdapter.setGenerateDdl(true);
        vendorAdapter.setShowSql(true);
        LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
        factory.setJpaVendorAdapter(vendorAdapter);
        factory.setPackagesToScan(environment.getRequiredProperty(PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN));
        factory.setDataSource(dataSource());
        factory.afterPropertiesSet();
        return factory.getObject();
    }

    @Bean
    public
            PlatformTransactionManager transactionManager()
    {
        JpaTransactionManager txManager = new JpaTransactionManager();
        txManager.setEntityManagerFactory(entityManagerFactory());
        return txManager;
    }
}

为了测试一切正常,我创建了这个方法

@Transactional
    public
            void doIt()
    {
        PersonDTO created = new PersonDTO();
        created.setId(null);
        created.setFirstName("Pluto");
        created.setLastName("Paperino");
        Person pippo= repositoryPersonService.create(created);
        for (int i = 0; i < 10; i++) {
            BookDTO bookDTO = new BookDTO();
            bookDTO.setTitle("Fantasia" + i);
            bookDTO.setPerson(pippo);
            repositoryBookService.create(bookDTO);
        }
        repositoryPersonService.findAll().stream().forEach((Person t) -> {
            System.out.println(t.getBooks());
        });
    }

我的实体是:

@Entity
@Table(name = "persons")
public
        class Person
        implements Serializable
{

    private static final
            long serialVersionUID = 198765467898765L;
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private
            Long id;
    @Column(name = "creation_time", nullable = false)
    @Temporal(javax.persistence.TemporalType.DATE)
    private
            Date creationTime;
    @Column(name = "first_name", nullable = false)
    private
            String firstName;
    @Column(name = "last_name", nullable = false)
    private
            String lastName;
    @Column(name = "modification_time", nullable = false)
    @Temporal(javax.persistence.TemporalType.DATE)
    private
            Date modificationTime;
    @OneToMany(fetch = FetchType.LAZY)
    private
            List<Book> books;
    @Version
    private
            long version = 0;

但是我收到了这条错误消息:

2014-04-09 12:31:54 TRACE LazyInitializationException:53 - 懒得初始化角色集合:it.myproject.data.person.Person.books,无法初始化代理 - 没有会话 org.hibernate.LazyInitializationException:懒得初始化一个角色集合:it.myproject.data.person.Person.books,无法初始化代理 - 没有会话

你能帮帮我吗? 谢谢

2 个答案:

答案 0 :(得分:3)

解决。我从配置中删除了“(mode = AdviceMode.ASPECTJ,proxyTargetClass = true)”,现在它工作正常。他们的家伙!

在─&GT;

@Configuration
@EnableJpaRepositories("it.myproject.data")
@EnableTransactionManagement(mode = AdviceMode.ASPECTJ, proxyTargetClass = true)
@PropertySource("classpath:/it/myproject/application.properties")

现在 - &gt;

@Configuration
@EnableJpaRepositories("it.myproject.data")
@EnableTransactionManagement
@PropertySource("classpath:/it/myproject/application.properties")

答案 1 :(得分:2)

似乎@Transactional无效,因为repositoryPersonService.findAll()正在返回分离实体的集合。然后,当尝试遍历这些实体并访问延迟初始化集合时,我们遇到LazyInitializationException

要确认这一点,请尝试在调用findAll的方法中放置断点,并查看是否正在应用事务方面。

要将@Transactional应用于测试方法,请查看它是由组件扫描捕获的Spring bean(使用ComponentScan("some.package")注释)。